【问题标题】:How to generate ALL floating numbers?如何生成所有浮点数?
【发布时间】:2013-08-31 04:10:04
【问题描述】:

我正在尝试将所有浮点数生成到 C++ 上的文件中(使用 gcc)。我的第一次尝试是使用FLT_MIN, FLT_MAX & FLT_EPSILON 来生成它们,代码是这样的:

#include <cfloat>
#include <stdio.h>
#include <iostream>

using namespace std;

int main(){
    FILE* handle = freopen("todos_los_float.in","w",stdout);
    for(float x = FLT_MIN; x < FLT_MAX; x = x + FLT_EPSILON)
        cout << x << endl;
    fclose(handle);
    return 0;
} 

这是行不通的,因为 FLT_EPSILON 破坏了数字的精度,对于 FLT_MIN,它需要一个巨大的跳跃,并且在达到 FLT_MAX 之前它会停止添加太多。

我考虑过在二进制形式上工作和添加,只是跳过特殊含义(inf、-inf、NaN),但我也不确定哪种方法最好。您建议如何生成数字?

【问题讨论】:

  • 您确实意识到会生成一个 40-80GB 大小的文件,对吗?
  • 您可能会发现Bruce Dawson's articles 很有用;它包括迭代所有浮点(单精度)值的示例。
  • 每个没有指数字段全一的 32 位模式代表一个有限数。
  • 关于文件大小...是的,这主要是出于好奇,但我仍将使用迭代进行一些数值分析的实际测试(在较小的范围内)。

标签: c++ floating-point numeric


【解决方案1】:

即使排除其他问题,您的循环也只会生成正浮点数。最小浮点数为-inf,最小的有限浮点数为-FLT_MAX

无论如何,如果您要生成所有正的有限浮点数,应该这样做:

#include <cfloat>
#include <cmath>
...
float f;
for (f=0.0f; f<INFINITY; f = nextafterf(f, INFINITY)) …

注意0.0以上的最小浮点数不是FLT_MIN,而是FLT_MIN * FLT_EPSILON。 也可以将 FPU 舍入模式设置为向上舍入并添加 FLT_MIN * FLT_EPSILON 直到达到 +inf。

【讨论】:

  • 谢谢!这真的很有用。我确实只对正数感兴趣,所以这正是我想要的。
【解决方案2】:

学习IEEE floating point format。然后简单地生成代表有限值的所有不同位模式(跳过所有INFs 和NaNs)。

【讨论】:

  • (a) 这不适用于所有浮点实现,而 nextafter 是可移植的。 (b) 这个答案声明生成位模式,但问题要求浮点数。所以它缺少将位模式转换为浮点数的步骤,这在不违反语言规则的情况下很难做到。
【解决方案3】:

std::nextafter:

for (float f = 0; f != FLT_MAX; f = std::nextafter(f, FLT_MAX)) { }

【讨论】:

  • 这是一个细节,但你的循环体没有为f == FLT_MAX执行。
猜你喜欢
  • 2010-10-15
  • 1970-01-01
  • 2012-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-14
相关资源
最近更新 更多