如何在特定机器上找到尾数长度?

时间:2009-02-02 02:13:56

标签: numerical-analysis rounding-error mantissa

我想在特定计算机上找到尾数位数和单位四舍五入。我对这些是什么有所了解,不知道如何找到它们 - 虽然我知道它们可能因计算机而异。

我需要这个数字才能执行数值分析的某些方面,比如分析错误。

我目前的想法是,我可以编写一个小的c ++程序来缓慢增加一个数字,直到溢出发生,但我不确定使用什么类型的数字。

我是否在正确的轨道上?一个人如何计算这个呢?

3 个答案:

答案 0 :(得分:5)

我认为您使用的任何语言都会指定浮点数的存储方式。我知道Java通过使用特定的IEEE标准(754,我认为)来做到这一点。

如果没有指定,我认为您可以通过添加0.5到1进行自己的检查,以查看实际数字是否发生变化。如果是,则添加0.25到1,将0.125添加到1,依此类推,直到数字不变,如:

float a = 1;
float b = 0.5;
int bits = 0;
while (a + b != a) {
    bits = bits + 1;
    b = b / 2;
}

如果你只有3个尾数位,那么1 + 1/16将等于1。

然后你已经用尽了尾数。

您可能实际上需要基数为2而不是1,因为IEEE754在开始时使用隐含的“1+”。

编辑:

看来上面描述的方法可能存在一些问题,因为它为一个明显具有4字节浮点数的系统提供了63位。

是否与中间结果有关(我怀疑它,因为具有显式强制转换[while (((float)(a + b) != (float)(a))]的相同代码具有类似问题)或(更可能,我相信)单位值{{1}的可能性通过调整指数,可以用更接近小数a的位表示,我还不知道。

目前,最好依赖我上面提到的语言信息,例如使用IEEE754(如果有这些信息)。

我会将有问题的代码留作警惕玩家的陷阱。也许有一个有更多浮点知识的人,然后我可以留下一个说明,解释为什么它行为奇怪(没有猜想,请: - )。

编辑2:

这段代码通过确保中间件存储在浮点数中来修复它。事实证明乔纳森莱弗勒是对的 - 这是中间结果。

b

}

此代码输出(24,24)以显示计算出的值与头文件中的值匹配。

虽然用C语言编写,但它应该适用于任何语言(特别是那些信息在标题中不可用或者在语言文档中指定的语言)。我只在C中测试过,因为Eclipse需要很长时间才能在我的Ubuntu盒子上启动: - )。

答案 1 :(得分:1)

对于C和扩展C ++,信息位于<float.h><cfloat>标题中。

对于C99,信息见标准的5.2.4.2.2节:

  • FLT_RADIX
  • FLT_MANT_DIG
  • FLT_DIG
  • FLT_EPSILON
  • FLT_MIN_EXP
  • FLT_MIN
  • FLT_MIN_10_EXP
  • FLT_MAX_EXP
  • FLT_MAX
  • FLT_MAX_10_EXP

同样对于大多数这些(无DBL_RADIXLDBL_RADIX)的DBL和LDBL变体。该标准建议的值适用于IEEE 754(1999年的IEEE 754标准的旧版本;我相信,2008年发布了新版本)。

答案 2 :(得分:1)

您可能想要查看C ++库中的<limits>

#include <iostream>
#include <limits>
#include <typeinfo>

template <typename T>
void printDetailsFor() {
    std::cout
        << "Printing details for " << typeid(T).name() << ":\n"
        << "\tradix:        " << std::numeric_limits<T>::radix        << "\n"
        << "\tradix digits: " << std::numeric_limits<T>::digits       << "\n"
        << "\tepsilon:      " << std::numeric_limits<T>::epsilon()    << "\n"
        << std::endl;
}

int main() {
    printDetailsFor<int>();
    printDetailsFor<float>();
    printDetailsFor<double>();
    printDetailsFor<long double>();
    return 0;
}

我认为您希望std::numeric_limits<T>::digits应该比尾数位的数量多一个。我的机器打印出来:

Printing details for i:
    radix:        2
    radix digits: 31
    epsilon:      0

Printing details for f:
    radix:        2
    radix digits: 24
    epsilon:      1.19209e-07

Printing details for d:
    radix:        2
    radix digits: 53
    epsilon:      2.22045e-16

Printing details for e:
    radix:        2
    radix digits: 64
    epsilon:      1.0842e-19