![](/img/trans.png)
[英]IEEE 754 floating point arithmetic rounding error in c# and javascript
[英]C# floating point rounding behavior
我一直在尝试解决由浮点算术引起的错误,并将其简化为导致我不了解行为的简单代码:
float one = 1;
float three = 3;
float result = one / three;
Console.WriteLine(result); // prints 0.33333
double back = three * result;
if (back > 1.0)
Console.WriteLine("larger than one");
else if (back < 1.0)
Console.WriteLine("less than one");
else
Console.WriteLine("exactly one");
结果舍入为0.33333,我希望返回到小于1,但是输出“大于1”。
有人可以解释这里发生了什么吗?
当我尝试上面的代码时,我发现
float result = one / three;
语句将result
的值评估为0.333333343
而不是0.33333
但控制台将其打印为0.33333
,然后执行以下语句
double back = three * result;
它将back
评估为1.0000000298023224
,显然大于1,这就是为什么您得到“大于1”的原因 。
使用IEEE 754取整,让我们看看发生了什么。
在IEEE 754单精度浮点中,有限数的值由以下各项决定:
-1 号 ×2 指数 ×(1 +尾数×2 -23 )
哪里
如果我们用0代替正负号 ,而用-2代替指数 ,那么我们保证数值在0.25和0.5之间。 为什么?
1×2 -2
是¼。 的价值
1 +尾数×2 -23
保证在1到2之间,所以这是我们的符号和指数排序。
继续前进,我们可以很快得出结论,可以将两个值用作尾数值:2796202和2796203。
将每个值替换为以下两个值(一个较低,一个较高):
精确值的二进制表示形式(最多22位)是:
1010101010101010101010...
由于下一位为1
,这意味着该值将向上舍入而不是向下舍入。 因此,较高的错误比较低的错误要小:
而且由于它大于精确值,因此乘以后将大于1。这就是为什么它使用最初显示的值的原因-二进制舍入有时与十进制舍入相反。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.