繁体   English   中英

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

[英]How to find mantissa length on a particular machine?

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

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

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

我在正确的轨道上吗? 究竟如何计算这个?

我认为您使用的任何语言都会指定浮点数的存储方式。 我知道 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)) ] 有类似的问题)或(更有可能,我相信)通过调整指数,单位值a可以用更接近小数b的位表示的可能性,我还不知道。

目前,最好依靠我上面提到的语言信息,例如 IEEE754 的使用(如果该信息可用)。

我会把有问题的代码留给谨慎的玩家。 也许有更多浮点知识的人然后我可以留下一个注释来解释它为什么会奇怪(没有猜想,请:-)。

编辑2:

这段代码通过确保中间体存储在浮点数中来修复它。 事实证明 Jonathan Leffler 是对的——这是中间结果。

#include <stdio.h>
#include <float.h>

int main(void) {
    float a = 1;
    float b = 0.5;
    float c = a + b;
    int bits = 1;
    while (c != a) {
        bits = bits + 1;
        b = b / 2;
        c = a + b;
    }
    printf("%d\n",FLT_MANT_DIG);
    printf("%d\n",bits);
    return 0;

}

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

虽然是用 C 编写的,但它应该适用于任何语言(特别是在标题中不提供信息或在语言文档中指定信息的情况下)。 我只在 C 中进行了测试,因为 Eclipse 需要很长时间才能在我的 Ubuntu 机器上启动 :-)。

您可能想查看 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

对于 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 和 LDBL 变体类似(没有DBL_RADIXLDBL_RADIX )。 该标准建议了适合 IEEE 754 的值(IEEE 754 标准的旧版本,1999 年生效;我相信,2008 年发布了一个新版本)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM