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