有没有办法以编程方式获得最接近1.0的double,但实际上不是1.0?
执行此操作的一种hacky方法是将double传递给相同大小的整数,然后减去一个。 IEEE754浮点格式的工作方式,最终将指数减少一,同时将小数部分从全零(1.000000000000)更改为全1(1.111111111111)。但是,存在一些机器,其中整数存储为little-endian,而浮点存储为big-endian,因此并不总是有效。
答案 0 :(得分:138)
从C ++ 11开始,您可以使用nextafter
在给定方向上获得下一个可表示的值:
std::nextafter(1., 0.); // 0.99999999999999989
std::nextafter(1., 2.); // 1.0000000000000002
答案 1 :(得分:25)
在C中,您可以使用:
#include <float.h>
...
double value = 1.0+DBL_EPSILON;
DBL_EPSILON
是1和可表示的大于1的最小值之间的差异。
您需要将其打印成几位数才能看到实际值。
在我的平台上,printf("%.16lf",1.0+DBL_EPSILON)
提供1.0000000000000002
。
答案 2 :(得分:22)
在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
代替。
答案 3 :(得分:4)
在C ++中,您也可以使用此
1 + std::numeric_limits<double>::epsilon()