最接近 1.0 的 double 不是 1.0 的是多少?
What's the closest double to 1.0, that isn't 1.0?
有没有办法以编程方式获取最接近 1.0 但实际上不是 1.0 的双精度值?
一个 hacky 方法是将双精度 memcpy 为相同大小的整数,然后减去一个。按照 IEEE754 浮点格式的工作方式,最终会将指数减一,同时将小数部分从全零 (1.000000000000) 更改为全一 (1.111111111111)。然而,存在整数以小端存储而浮点数以大端存储的机器,因此这并不总是有效。
自 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()
在 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
代替。
有没有办法以编程方式获取最接近 1.0 但实际上不是 1.0 的双精度值?
一个 hacky 方法是将双精度 memcpy 为相同大小的整数,然后减去一个。按照 IEEE754 浮点格式的工作方式,最终会将指数减一,同时将小数部分从全零 (1.000000000000) 更改为全一 (1.111111111111)。然而,存在整数以小端存储而浮点数以大端存储的机器,因此这并不总是有效。
自 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()
在 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
代替。