为什么 double.MaxValue + double.Epsilon 不等于 double.Infinity?

4
我正在阅读这篇答案,但有一点我不明白。也许是因为我具有数学家的思维方式,所以如果问题太简单,请原谅。
为什么这不会得到无穷大?
double.MaxValue + double.Epsilon

无论Epsilon的值有多小,只要它加到最大值上,就应该使最大值增加一小精度。为什么在这种情况下没有增加呢?

这是我一直在实验的 dotnetfiddle


2
不是答案:您是否意识到要更改接近MaxValue的“double”值,您需要将其修改为非常大(随机猜测10 ^ 10?)增量?或者也许这是一个答案...当值大于MaxValue时,Double.PositiveInfinity返回,但添加如此小的增量根本不会改变它。 - Alexei Levenkov
2
这里有另一个答案可以帮助你:https://dev59.com/32855IYBdhLWcg3wm1i3 - mybirthname
2
@mybirthname 我认为这是完美的副本...(而我的增量猜测有点偏差 - 你需要添加1E292d :)) - Alexei Levenkov
1个回答

2
在默认的最近舍入模式下,加法的数学结果必须高于 double.MaxValue 和下一个可表示的浮点数之间中点的位置,如果浮点数结果的指数范围更宽,则结果要向上舍入为正无穷大。
产生数学结果介于 double.MaxValue 和该中点之间的操作将向下舍入为 double.MaxValuedouble.Epsilon 远小于 double.MaxValue 和该中点之间的距离,因此浮点加法的结果为 double.MaxValue
这种现象通常被称为“吸收现象”(不仅当其中一个加数为 double.MaxValue 时,而且只要加数之间的比率使结果与最大的加数相同)。

出于好奇,我在测试值达到无穷大之前的极限。结果发现,var i = double.MaxValue - 100000000000000000000000000000000000000000000000000000000000000000000.0; (i == double.MaxValue).Dump(); 返回 true。我的第一次测试是减去1,我认为这是由于精度问题。但这怎么可能呢..? - Rob
2
@Rob,我认为mybirthname找到的答案也解释了这个问题。 - Alexei Levenkov
1
@Rob 100000000000000000000000000000000000000000000000000000000000000000000.0(大约70个零)比double.MaxValue(~1e308)小得多,甚至比如果指数范围更宽,则double.MaxValue和下一个可表示的浮点数之间的差异要小(去掉约16个零,结果应该在1e292左右,误差可能为100倍左右) 。 - Pascal Cuoq
@AlexeiLevenkov - 谢谢你们俩,现在我明白了 :) - Rob
@Rob 添加任何小于179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497792的值都会导致DBL_MAX。(这是DBL_MAX的1/2 ULP) - Rick Regan
@Rob 根据你的示例进行加减操作。 - Rick Regan

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