编程语言
首页 > 编程语言> > c# – ToString中的.NET舍入错误(“f2”)

c# – ToString中的.NET舍入错误(“f2”)

作者:互联网

你好,我在C#中有这个代码:

float n = 2.99499989f;
MessageBox.Show("n = " + n.ToString("f2", CultureInfo.InvariantCulture));

这段代码用C:

float n = 2.99499989f;
printf("n = %.2f", n);

第一个输出3.00.
第二个输出2.99.

我不知道为什么会这样.

更新:

我也尝试了Objective-C NSLog,输出为2.99.

我需要快速修复它,所以我使用以下方法:

float n = 2.99499989f;
float round = (float)Math.Round(n, 2);
MessageBox.Show("round = " + round.ToString(CultureInfo.InvariantCulture));

此代码显示2.99,但以双精度计算舍入.我找不到Math.RoundF.

解决方法:

(我意识到这是一个老问题,但我正在回答这个问题,因为我自己理解了一些事情……)

我的建议是“printf”在应用格式化之前将float转换为double.
我尝试将float转换为double,然后查看double的ToString(“f2”)结果,当float的值被舍入时,它在相反的方向上进行了舍入.

其他人重新强化了关于printf的想法:

C automatically converts the float values to double (it is a standard conversion made when you call a function that takes variable arguments, such as int printf…

https://stackoverflow.com/a/7480244/119418

https://stackoverflow.com/a/6395747/119418

我认为浮动汇总的原因是因为2.995F没有完美地转换成二进制并且是= 2.99499989F,我们期望2.995向上舍入.

我相信浮动复制到双舍入的原因是因为2.995作为双倍<> 2.99499989为double,2.995实际double值大于该值(更接近其真实十进制值的精度),以及我们期望舍入的值.

似乎错误2.99499989F虽然看起来小于2.995但最终回合3.00但是请记住2.99499989是小数,而不是浮点数,并且你将它“转换”成浮点数,基本上是转换基数 – 10到base-2,它实际上是1和0,然后要求它在基数为10的条件下舍入,这意味着必须进行转换.好吧,我提到的至少有2个基数为10的值可以转换为浮点数,其中最简单的是2.995.

标签:c,c-2,rounding-error
来源: https://codeday.me/bug/20190518/1130735.html