我试图从一个浮点数到下一个完全循环.比如说,我需要从std :: numeric_limits< float> :: epsilon()循环到1,它们都是完全可表示的IEEE754数字.我的代码是:
using nld = std::numeric_limits<float>;
auto h = nld::epsilon();
for (; h < 1; h = std::nextafter(h, 1)) {
std::cerr << "h: " << h << std::endl;
}
无限循环,因为h是完全可以表示的,所以nextafter不断返回它.我也知道在循环中将机器epsilon添加到h不会削减它:浮点数不是等间隔的.如何循环IEEE754数字的确切表示?
不等间距的问题出现在这里:
using nld = std::numeric_limits<float>;
auto h = nld::epsilon();
for (; h < 4; h += nld::epsilon()) {
if (h = h + nld::epsilon()) {
std::cerr << "h: " << h << std::endl;
}
}
这为我保留了打印2
最佳答案 根据评论:
nextafter的方法正是你应该做的.但是,它有一些可能导致意外结果的并发症.
引用cppreference std::nextafter
:
float nextafter( float from, float to );
(1) (since C++11)
double nextafter( double from, double to );
(2) (since C++11)
long double nextafter( long double from, long double to );
(3) (since C++11)
Promoted nextafter( Arithmetic from, Arithmetic to );
(4) (since C++11)…
4) A set of overloads or a function template for all combinations of arguments of arithmetic type not covered by (1-3). If any argument has integral type, it is cast to
double
. If any argument islong double
, then the return typePromoted
is alsolong double
, otherwise the return type is alwaysdouble
.
由于你的to是1,类型为int,你得到重载版本4,返回类型为double.现在,完全有可能给定一个浮点数f,(浮点数)nextafter((double)f,1)与原始f完全相等:很可能,double类型中的下一个可表示数字不能用float表示,转换回浮动向下舍入.
返回float的唯一重载是float类型.要使用该重载,请使用1.0f而不是1.