c++ - 如何遍历 float 的​​精确表示?

标签 c++ loops ieee-754

我试图从一个 float 精确地循环到下一个。说,我需要从 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 不会削减它: float 不是等间距的。如何遍历 IEEE754 数字的精确表示?

not equally spaced问题出现在这里:

 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 is long double, then the return type Promoted is also long double, otherwise the return type is always double.

由于您的to1,属于int 类型,您得到重载版本4,返回类型为double。现在,完全有可能给定一个 float f(float)nextafter((double)f, 1) 完全等于原始 f:double 类型的下一个可表示数字很可能无法用 float 表示,并且转换回 float 会向下舍入。

返回 float 的唯一重载是 to 的类型为 float 的重载。要使用该重载,请使用 1.0f 而不是 1

关于c++ - 如何遍历 float 的​​精确表示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27329921/

相关文章:

c++ - 尽管#ifndef,头文件仍被包含两次

c++ - 奇怪的 const 正确性错误

c - 使用 IEEE float 表示的最大负实数

c - 使用浮点二进制的算术运算 "0b"

javascript - 为什么 console.log 只显示 0.1+0.2=0.30000000000000004 产生的部分数字

c++ - 在工厂类中使用单例 (C++)

c++ - 使用 cv::Mat boost Python 包装器和 OpenCv 参数错误

c - 有没有一种简单的方法可以让用户在每次选择后返回到菜单?

C++ If 在 for 循环中循环。限制

python - 在第二个列表的条件下对列表元素求和