为什么"(Double.MinValue + 1) > Double.MinValue"的结果是false?

11

我最初尝试了这个(用vb.net)

(Double.MinValue + Double.Epsilon) > Double.MinValue

但是那个结果为假。然后我尝试了这个

(Double.MinValue + 999999999999999999) > Double.MinValue

那也是 false 的评估结果。

为什么?


现在我发现了http://msdn.microsoft.com/de-de/library/system.double.epsilon%28v=vs.110%29.aspx:“然而,Epsilon属性并不是Double类型精度的一般度量;它仅适用于具有零值或指数为-1022的Double实例。” - habakuk
1个回答

15

将一个非常小的(数量级)值加到一个非常大的(数量级)中几乎不会有任何影响。在这种情况下,差异非常小,以至于它在double的精度范围内无法表示。基本上:

double.MinValue + (most things) === double.MinValue

它不能保证能够表示double.MinValuedouble.MaxValue之间每一个double值,随着数值的增加,所能表示的绝对精度会降低。

不要忘记:double.MinValue在小数点前有308位数字。你只改变了其中极少量的数字。你基本上在做以下操作:

-179769313486232000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000 // yikes!
+ 999999999999999999

请记住,double 大约有17个有效数字,所以那个巨大的数字中大约可以忽略291位数字。


如果想要一个比double.MinValue稍微不那么负的数字,那么double.MinValue * 0.999999999999 > double.MinValue应该是可行的。 - gnasher729
我认为应该是 double.MinValue + most_things === most_things - Mike
@MarcGravell 我错了,我以为 double.MinValue 是具有最小幅度的数字 (~1e-308),我没有意识到它是一个具有较大幅度的负数。 - Mike

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接