小编典典

使用 epsilon 将双精度数与零进行比较

all

今天,我浏览了一些 C++ 代码(由其他人编写)并找到了这一部分:

double someValue = ...
if (someValue <  std::numeric_limits<double>::epsilon() && 
    someValue > -std::numeric_limits<double>::epsilon()) {
  someValue = 0.0;
}

我试图弄清楚这是否有意义。

的文档epsilon()说:

该函数返回 1 和大于 1 的最小值之间的差值,该值可以 [用双精度值] 表示。

这是否也适用于 0,即epsilon()最小值是否大于 0?或者0和之间是否有0 + epsilon可以用 a 表示的数字double

如果不是,那么比较不等于someValue == 0.0


阅读 85

收藏
2022-06-14

共1个答案

小编典典

假设 64 位 IEEE double,则有 52 位尾数和 11 位指数。让我们将其分解为:

1.0000 00000000 00000000 00000000 00000000 00000000 00000000 脳 2^0 = 1

大于 1 的最小可表示数:

1.0000 00000000 00000000 00000000 00000000 00000000 00000001 脳 2^0 = 1 + 2^-52

所以:

epsilon = (1 + 2^-52) - 1 = 2^-52

0和epsilon之间有数字吗?很多......例如,最小的正可表示(正常)数是:

1.0000 00000000 00000000 00000000 00000000 00000000 00000000 脳 2^-1022 = 2^-1022

事实上,(1022 - 52 + 1)脳2^52 = 4372995238176751616在 0 和 epsilon
之间存在数字,占所有可表示的正数的 47%…

2022-06-14