是否有公式可以找到浮点数中指数或有效位数的位数?

Ran*_*tep 4 c c++ floating-point bit-manipulation

最近,我对在浮点数上使用位移位进行一些快速计算很感兴趣。

为了让它们以更通用的方式工作,我想让我的函数使用不同的浮点类型,可能是通过模板,不仅限于floatand double,还有“半宽”或“四倍宽”浮点数等等.


然后我注意到:

 - Half   ---  5 exponent bits  ---  10 signicant bits
 - Float  ---  8 exponent bits  ---  23 signicant bits
 - Double --- 11 exponent bits  ---  52 signicant bits
Run Code Online (Sandbox Code Playgroud)

到目前为止,我认为exponent bits = logbase2(total byte) * 3 + 2
这意味着 128 位浮点数应该有 14 个指数位,而 256 位浮点数应该有 17 个指数位。


然而,后来我了解到:

 - Quad   --- 15 exponent bits  ---  112 signicant bits
 - Octuple--- 19 exponent bits  ---  237 signicant bits
Run Code Online (Sandbox Code Playgroud)

那么,有没有一个公式可以找到它?或者,有没有办法通过一些内置函数来调用它?
C 或 C++ 是首选,但对其他语言开放。

谢谢。

Eri*_*hil 5

通过内置函数提供的特性

C++ 通过std::numeric_limits模板提供此信息:

#include <iostream>
#include <limits>
#include <cmath>


template<typename T> void ShowCharacteristics()
{
    int radix = std::numeric_limits<T>::radix;

    std::cout << "The floating-point radix is " << radix << ".\n";

    std::cout << "There are " << std::numeric_limits<T>::digits
        << " base-" << radix << " digits in the significand.\n";

    int min = std::numeric_limits<T>::min_exponent;
    int max = std::numeric_limits<T>::max_exponent;

    std::cout << "Exponents range from " << min << " to " << max << ".\n";
    std::cout << "So there must be " << std::ceil(std::log2(max-min+1))
        << " bits in the exponent field.\n";
}


int main()
{
    ShowCharacteristics<double>();
}
Run Code Online (Sandbox Code Playgroud)

示例输出:

浮点基数为 2。
有效数中有 53 个基数为 2 的数字。
指数范围从 -1021 到 1024。
所以指数字段中必须有 11 位。

C还提供了信息,通过宏定义等DBL_MANT_DIG所定义<float.h>的,但该标准定义了仅针对类型的名称float(前缀FLT), (double),DBLlong doubleLDBL),所以在C实现一个支持附加的浮点类型的名称将不可预测的。

请注意,C 和 C++ 标准中指定的指数与 IEEE-754 中描述的常用指数不同:它针对缩放为 [½, 1) 而不是 [1, 2) 的有效数进行调整,因此它是 1大于通常的 IEEE-754 指数。(上面的例子显示指数范围从 ?1021 到 1024,但 IEEE-754 指数范围是?1022 到 1023。)

公式

IEEE-754 确实提供了推荐字段宽度的公式,但它不要求 IEEE-754 实现符合这些,当然 C 和 C++ 标准不要求 C 和 C++ 实现符合 IEEE-754。交换格式参数在 IEEE 754-2008 3.6 中规定,二进制参数为:

  • 对于 16、32、64 或 128 位的浮点格式,有效位宽度(包括前导位)应为 11、24、53 或 113 位,指数字段宽度应为 5、8、11,或 15 位。
  • Otherwise, for a floating-point format of k bits, k should be a multiple of 32, and the significand width should be k?round(4•log2k)+13, and the exponent field should be round(4•log2k)?13.

  • +1用于追踪参考。最后一点可能值得注意的是,该公式仅适用于“k &gt;= 128”(它实际上也与“k = 64”的“11”位匹配,但它偏离了“1”,并且“2”代表“k = 32, 16”)。 (2认同)