最接近 1.0 的双倍是什么,那不是 1.0?

What's the closest double to 1.0, that isn't 1.0?

本文关键字:最接近 是什么      更新时间:2023-10-16

有没有一种方法可以通过编程获得最接近1.0的double,但实际上不是1.0?

要做到这一点,一种巧妙的方法是将双精度记忆为相同大小的整数,然后减去一。按照IEEE754浮点格式的工作方式,这最终会使指数减少一,同时将小数部分从全零(1 000000000000(更改为全一(1 111111111111(。然而,有些机器的整数存储为小端序,而浮点存储为大端序,因此这并不总是有效的。

由于C++11,您可以使用nextafter来获得给定方向上的下一个可表示值:

std::nextafter(1., 0.); // 0.99999999999999989
std::nextafter(1., 2.); // 1.0000000000000002

演示

在C和C++中,以下给出了最接近1.0的值:

#include <limits.h>
double closest_to_1 = 1.0 - DBL_EPSILON/FLT_RADIX;

但是,请注意,在C++的后续版本中,limits.h被弃用,而climits被弃用。但是,如果你无论如何都在使用C++特定的代码,你可以使用

#include <limits>
typedef std::numeric_limits<double> lim_dbl;
double closest_to_1 = 1.0 - lim_dbl::epsilon()/lim_dbl::radix;

正如Jarod42在他的回答中所写的那样,由于C99或C++11,您也可以使用nextafter:

#include <math.h>
double closest_to_1 = nextafter(1.0, 0.0);

当然,在C++中,您可以(对于以后的C++版本应该(包括cmath,而使用std::nextafter

在C中,您可以使用以下内容:

#include <float.h>
...
double value = 1.0+DBL_EPSILON;

CCD_ 7是1和可表示的大于1的最小值之间的差。

您需要将其打印到几个数字才能看到实际值。

在我的平台上,printf("%.16lf",1.0+DBL_EPSILON)给出了1.0000000000000002

在C++中,您也可以使用此

1 + std::numeric_limits<double>::epsilon()