转换为小数而不舍入

时间:2013-04-22 12:25:36

标签: c# decimal

我有一个浮点数,比如1.2999,当放入Convert.ToDecimal时会返回1.3。我想将数字转换为小数的原因是加法和减法时的精度,而不是舍入。我确信十进制类型可以保存该数字,因为它可以容纳大于浮点数的数字。

为什么要将数字四舍五入?反正有没有阻止它四舍五入?

编辑:我不知道为什么我的是四舍五入而你的不是,这是我的确切代码:

decNum += Convert.ToDecimal((9 * 0.03F) + 0);

我现在很困惑。当我进入调试器并查看(9 * 0.03F) + 0部分的输出时,它将0.269999981显示为float,但随后将其转换为0.27十进制。但我知道9%的3%是0.27。那么这是否意味着原始计算不正确,转换只是修复它?

该死的我非常讨厌数字哈哈!

1 个答案:

答案 0 :(得分:7)

你说的话似乎没有发生。

这个程序:

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            float f = 1.2999f;
            Console.WriteLine(f);
            Decimal d = Convert.ToDecimal(f);
            Console.WriteLine(d);
        }
    }
}

打印:

1.2999
1.2999

我认为将值转换为字符串时可能会遇到问题。

或者,正如ByteBlast在下面所说,也许你给了我们错误的测试数据。

使用float f = 1.2999999999f; 打印1.3

原因是浮点值不够精确,无法准确表示1.299999999f。该特定值最终被舍入为1.3 - 但请注意, float 值在转换为小数之前被舍入

如果您使用的是double而不是float,除非您获得更多的精度数字(当您到达1.299999999999999时),否则不会发生这种情况。

[编辑] 根据您修改后的问题,我认为这只是预期的舍入错误,所以请务必阅读以下内容:

有关详细信息,请参阅"What Every Computer Scientist Should Know About Floating-Point Arithmetic"

Also see this link(Tim Schmelter在下面的评论中推荐)。

另一件需要注意的事情是,调试器可能会将数字显示为与默认double.ToString()(或等效)不同的精度级别,这样可能会导致您看到的数字略有不同。


除了:

您可能会对“往返”格式说明符运气不错:

 Console.WriteLine(1.299999999999999.ToString());
 Prints 1.3

可是:

Console.WriteLine(1.299999999999999.ToString("r"));
Prints 1.2999999999999989

(请注意,倒数第二位的偷偷摸摸的小8!)

为获得最高精确度,您可以使用the Decimal type,就像您已经在做的那样。这针对基数为10的数字进行了优化,并提供了更多的精确数字。

但请注意,它比floatdouble慢了几百倍,并且它也会受到舍入错误的影响,尽管要少得多。