首页 > 解决方案 > 以十六进制格式表示 fp16 最小数字

问题描述

我需要在我的程序中使用 float16 的 min_value,但不想以十进制格式显式写出它。我想知道如何以十六进制格式表示它。

float FP16_MIN = 5.96e-8;

根据我收到的最佳答案, fp16 min 与 denorm 的十六进制代码是0001.

我想要一个功能:

float min = fp16_min(0x1); 

我在https://eigen.tuxfamily.org/dox/Half_8h_source.html的第 185 行发现了一个类似的函数,但我不明白它的实现。

标签: c++floating-point

解决方案


对于 FP16,最小正正常值为:

                  1       0
                  5 43210 9876543210
                  S -E5-- ---F10----
          Binary: 0 00001 0000000000
             Hex: 0400
       Precision: HP
            Sign: Positive
        Exponent: -14 (Stored: 1, Bias: 15)
       Hex-float: +0x1p-14
           Value: +6.1035156e-5 (NORMAL)

最小正次正规值是:

                  1       0
                  5 43210 9876543210
                  S -E5-- ---F10----
          Binary: 0 00000 0000000001
             Hex: 0001
       Precision: HP
            Sign: Positive
        Exponent: -14 (Stored: 0, Bias: 14)
       Hex-float: +0x1p-24
           Value: +5.9604645e-8 (DENORMAL)

您可以将前者编写为程序0x1p-14,将后者编写为0x1p-24程序。

如果您想从底层的十六进制表示进行转换,那么一个常见的技巧是在 C 中使用联合,memcpy在 C++ 中使用 a。有关详细信息,请参阅此答案:如何在 C/C++ 中将 1 编码为浮点数(假设 IEEE 754 单精度表示)?

当然,要正确执行此操作,您需要一个底层的 16 位浮点类型;这通常是不可用的。因此,您必须首先弄清楚 32 位单精度格式中对应的十六进制是什么。因为1p-24这很容易以单精度计算:

                  3  2          1         0
                  1 09876543 21098765432109876543210
                  S ---E8--- ----------F23----------
          Binary: 0 01100111 00000000000000000000000
             Hex: 3380 0000
       Precision: SP
            Sign: Positive
        Exponent: -24 (Stored: 103, Bias: 127)
       Hex-float: +0x1p-24
           Value: +5.9604645e-8 (NORMAL)

因此,作为单精度浮点数的相应表示将是0x33800000. (这不难看出:32 位浮点数的偏差为 127,因此您只需将 103 放入指数中即可得到 -24。我相信您自己可以轻松做到这一点;如果不问的话。)

现在你可以写:

#include <inttypes.h>
#include <iostream>

int main(void) {
    uint32_t abc = 0x33800000;
    float i;
    std::memcpy(&i, &abc, 4);
    std::cout<< i << std::endl;
    return 0;
}

打印:

5.96046e-08

推荐阅读