转换为小数而不舍入

The*_*per 0 c# decimal

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

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

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

decNum += Convert.ToDecimal((9 * 0.03F) + 0);
Run Code Online (Sandbox Code Playgroud)

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

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

Mat*_*son 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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

打印:

1.2999
1.2999
Run Code Online (Sandbox Code Playgroud)

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

另外,正如下面的ByteBlast所说,也许你给了我们错误的测试数据.

使用float f = 1.2999999999f; 确实打印1.3

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

如果你使用a double而不是a float,除非你去更精确的数字(当你到达时1.299999999999999),这不会发生

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

有关详细信息,请参阅"每个计算机科学家应该知道的关于浮点算术的内容".

另请参阅此链接(Tim Schmelter在下面的评论中推荐).

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


在旁边:

你可能会对"往返"格式说明符运气不错:

 Console.WriteLine(1.299999999999999.ToString());
 Prints 1.3
Run Code Online (Sandbox Code Playgroud)

但:

Console.WriteLine(1.299999999999999.ToString("r"));
Prints 1.2999999999999989
Run Code Online (Sandbox Code Playgroud)

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

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

但是,要知道,它比慢数百倍float或者double,它也可以从舍入误差,虽然少得多苦.