使用 epsilon 将双精度数与零进行比较
今天,我翻阅了一些 C++ 代码(由其他人编写),发现了这个部分:
Today, I was looking through some C++ code (written by somebody else) and found this section:
double someValue = ...
if (someValue < std::numeric_limits<double>::epsilon() &&
someValue > -std::numeric_limits<double>::epsilon()) {
someValue = 0.0;
}
我正在尝试弄清楚这是否有意义.
I'm trying to figure out whether this even makes sense.
epsilon()
的文档说:
该函数返回 1 和大于 1 的最小值之间的差值,该值可以 [用双精度数] 表示.
The function returns the difference between 1 and the smallest value greater than 1 that is representable [by a double].
这是否也适用于 0,即 epsilon()
是大于 0 的最小值?或者 0
和 0 + epsilon
之间是否有可以用 double
表示的数字?
Does this apply to 0 as well, i.e. epsilon()
is the smallest value greater than 0? Or are there numbers between 0
and 0 + epsilon
that can be represented by a double
?
如果不是,那么比较不等于 someValue == 0.0
?
If not, then isn't the comparison equivalent to someValue == 0.0
?
推荐答案
假设 64 位 IEEE 双精度,有 52 位尾数和 11 位指数.让我们分解一下:
Assuming 64-bit IEEE double, there is a 52-bit mantissa and 11-bit exponent. Let's break it to bits:
1.0000 00000000 00000000 00000000 00000000 00000000 00000000 × 2^0 = 1
大于1的最小可表示数:
The smallest representable number greater than 1:
1.0000 00000000 00000000 00000000 00000000 00000000 00000001 × 2^0 = 1 + 2^-52
因此:
epsilon = (1 + 2^-52) - 1 = 2^-52
0 和 epsilon 之间有数字吗?很多...例如最小正可表示(正常)数是:
Are there any numbers between 0 and epsilon? Plenty... E.g. the minimal positive representable (normal) number is:
1.0000 00000000 00000000 00000000 00000000 00000000 00000000 × 2^-1022 = 2^-1022
实际上在 0 和 epsilon 之间有 (1022 - 52 + 1)×2^52 = 4372995238176751616
个数,占所有可表示正数的 47%...
In fact there are (1022 - 52 + 1)×2^52 = 4372995238176751616
numbers between 0 and epsilon, which is 47% of all the positive representable numbers...
相关文章