ieee-754 - IEEE 754 binary16 半 float 的类似 float.h 的定义

标签 ieee-754 half-precision-float

我使用的是在 SoftFloat 库中实现的半 float (阅读:100% IEEE 754 兼容),为了完整起见,我希望为我的代码提供与 float.h> 用于 floatdoublelong double

我知道有不同风格的半 float ,但我只对 IEEE 754 的标准化部分感兴趣,称为 binary16

根据我的研究和测试,我有信心定义一些常量如下:

#define HALF_MANT_DIG      11
#define HALF_DIG           3
#define HALF_DECIMAL_DIG   5
#define HALF_EPSILON       UINT16_C(0x1400) /* 0.00097656 */
#define HALF_MIN           UINT16_C(0x0400) /* 0.00006103515625 */
#define HALF_MAX           UINT16_C(0x7BFF) /* 65504.0 */

注意:epsilon、min 和 max 定义为该类型采用的 16 位的原始十六进制表示。将原始值分配给类型的正确方法取决于所使用的半 float 库。

但是,对于与指数相关的定义,我未能达成共识。我看过Wikipedia page for binary16 , 在这other SO question , 在 Half library ,以及 GitHub 和其他地方的其他几个代码。

proposal linked从另一个 SO 问题听起来对我来说很有声望,以及 Half library 好消息是它们匹配。但是,我在 FP16.java implementation 发现了分歧。 , 在 this implementation , 在 Zig language implementation ,并在 Sargon对于 D.

#define HALF_MIN_EXP     The article and Half say (-13) but FP16.java and sargon say (-14) 
#define HALF_MAX_EXP     The article and Half say 16 but others say 14 or 15
#define HALF_MIN_10_EXP  The article and Half say (-4) but sargon says (-5)
#define HALF_MAX_10_EXP  The article and Half say 4 but sargon says 5

我想这篇文章和 Half 可能是正确的来源,但是,我能确定 IEEE 754 binary16 的良好值吗?

最佳答案

#define HALF_MANT_DIG 11

是的,binary16 格式有 11 个有效数字(位)。 (10 存储在主要有效数字字段中,1 通过指数字段编码。)

#define HALF_DIG 3

我手头没有引用资料,所以不做评论。但这可以毫不费力地进行测试。

#define HALF_DECIMAL_DIG 5

IEEE 754-2019 将其定义为 1+ceiling(p×log10(2)),其中 p 是“数字格式中的有效位”,因此为 11,因此 1+ceiling(11•.3010299957) = 1+ceiling(3.3) = 1+4 = 5。

#define HALF_EPSILON UINT16_C(0x1400) /* 0.00097656 */

是的,有 11 个有效位,1 表示为高位 20 和低位 2−10,即 .0009765625。这是用 15 的指数偏差编码的,因此指数字段中为 5,所以 5 << 11 , 即 140016

#define HALF_MIN UINT16_C(0x0400) /* 0.00006103515625 */

是的,最小正态指数编码为1,去除偏差得到-14,即.00006103515625,指数字段中的1给出 0400<子>16

#define HALF_MAX UINT16_C(0x7BFF) /* 65504.0 */

是的,最大正规指数字段是30,30 << 11给出 780016 并且最大有效数字段是 11111111112 = 3FF16,将它们合并给出 7BFF16。去除 15 的指数偏差得到 15,因此表示的值为 215•(2−2−10) = 65,504。

#define HALF_MIN_EXP The article and Half say (-13) but FP16.java and sargon say (-14)
#define HALF_MAX_EXP The article and Half say 16 but others say 14 or 15

C 将浮点表示定义为有效数位在小数点之后开始,而不是在小数点之前有一个,其余的在小数点之后。也就是说,对于基数为 b 的浮点格式,有效数在 [1/b, 1) 而不是 [1, b>).这在 *_MIN_EXP 的值中可见和 *_MAX_EXPfrexp 的行为函数,并且指数与 IEEE 754 中使用的更常见定义相差一个。

根据 IEEE-754,指数范围是 [−14, 15],因此,对于 C 标准的缩放,它是 [−13, 16]。

#define HALF_MIN_10_EXP The article and Half say (-4) but sargon says (-5)

C 2018 5.2.4.2.2 12 表示这是 ⌈log10bemin−1⌉,其中 eminHALF_MIN_EXP , 所以我们有 ⌈log102−13−1⌉ = ⌈−4.2144…⌉ = −4。我们从HALF_MIN知道高于 10−4 是在正常范围内,而 10−5 不是,所以 −4 是“最小负整数,使得 10 的次方在范围内归一化 float ”,也在 5.2.4.2.2 12 中。

#define HALF_MAX_10_EXP The article and Half say 4 but sargon says 5

如上,C 标准将其表示为 ⌊log10((1−b− p)bemax)⌋ = ⌊log10((1−2− 11)2 16)⌋ = ⌊log10((1−2− 11)216)⌋ = ⌊log 10(65,504)⌋ = ⌊4.8162…⌋ = 4,而 104 低于 HALF_MAX但是 105 不是。

关于ieee-754 - IEEE 754 binary16 半 float 的类似 float.h 的定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73529209/

相关文章:

ieee-754 - 将科学记数法的十进制数转换为 IEEE 754

c++ - 为什么没有 2 字节 float 并且已经存在实现?

c - 随机生成带 float 的 C 程序

c - 获取 unsigned int 或 float 的(float 的)尾数 (C)

assembly - MIPS 中的 IEEE 754(不带 FPU)

javascript - javascript中,按位或运算时是否使用iee-754作为存储格式?

x86 - 英特尔芯片上的半精度浮点算法

intrinsics - 使用 AVX 收集半浮点值

c++ - 在 Clang 9 上将 __fp16 转换为 float 无法链接