在C++中,我们知道可以使用std::numeric_limits<double>::min()
来找到最小的可表示双精度值,打印出来的结果是2.22507e-308
。
现在,如果从这个最小值中减去给定的双精度值(比如val
),然后用之前相同的双精度值(val - minval) / val
相除,如果对所得相除值执行floor((val - minval ) / val)
运算,我预计答案将舍入为0
。
令我惊讶的是,答案是1
。有人能解释一下这种异常行为吗?
请看下面的代码:
int main()
{
double minval = std::numeric_limits<double>::min(), wg = 8038,
ans = floor((wg - minval) / wg); // expecting the answer to round to 0
cout << ans; // but the answer actually resulted as 1!
}
1条答案
按热度按时间o4hqfura1#
一个double通常有大约16位的精度。
我们从8038开始,为了简单起见,我将它命名为
8.038e3
,因为我们有大约16位的精度,所以从8038中减去的最小值是8038 e(3-16)= 8038 e-13。8038 - 2.2e-308就像将宇宙的质量减少一个电子,并期望这会对宇宙的质量产生显著的影响。
实际上,相对而言,8038-2.2e-308比从宇宙中移除一个完整的电子要“小”得多--更像是从宇宙中移除一个电子的极小部分,如果这是可能的话。即使我们假设弦理论是正确的,与8038减去2.2e-308相比,即使从宇宙中去掉一根弦也是一个巨大的变化。