什么是1.0最接近的两倍,那不是1.0?
有没有一种方法来编程获得最接近1.0,但实际上不是1.0的双?
一个不好的方法就是把double加memcpy到一个相同大小的整数,然后减去一个。 IEEE754浮点格式的工作方式是,将小数部分从全零(1.000000000000)改为全1(1.111111111111),指数减1。 但是,存在整数以小端存储,而浮点以大端存储的机器,所以并不总是工作。
在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 ++ 11,您可以使用nextafter
在给定的方向获得下一个可表示的值:
std::nextafter(1., 0.); // 0.99999999999999989 std::nextafter(1., 2.); // 1.0000000000000002
演示
在C中,你可以使用这个:
#include <float.h> ... double value = 1.0+DBL_EPSILON;
DBL_EPSILON
是1和大于1的最小值之间的差值,可以表示。
您需要将其打印到几位数字才能看到实际值。
在我的平台上, printf("%.16lf",1.0+DBL_EPSILON)
给出1.0000000000000002
。
在C ++中,你也可以使用这个
1 + std::numeric_limits<double>::epsilon()