一尘不染

Swift为什么将基数2用作十六进制浮点值的指数?

swift

根据 Swift编程语言

例如,0xFp2表示15×2 ^ 2,其值为60。类似地,0xFp-2表示15×2 ^(-2),其值为3.75。

为什么使用2作为指数的底数而不是16?我本来期望0xFp2 == 15 * (16**2)而不是0xFp2 == 15 * (2**2)


阅读 293

收藏
2020-07-07

共1个答案

一尘不染

Swift的十六进制浮点数表示法只是C99标准为输入和输出(使用printf
%a格式)为C引入表示法的一种变体。

该表示法的目的是使人易于理解,并使IEEE 754表示法的位易于识别。IEEE
754表示法使用基数二。因此,对于正常的浮点数,当before的数量在和p之间时,after的数量直接是IEEE
754表示形式的指数字段的值。这符合人类可读性和接近位表示的双重目标:1``2``p

$ cat t.c
#include <stdio.h>

int main(){
  printf("%a\n", 3.14);
}
$ gcc t.c && ./a.out 
0x1.91eb851eb851fp+1

0x1.91eb851eb851fp+1可以看到该数字略高于3,因为指数为1,并且有效数接近0x1.9,略高于0x1.8,这表示两个2的幂之间的正中间。

这种格式有助于记住以十进制表示的数字不一定是二进制的简单数字。在上面的示例中,3.14使用有效数字的所有数字进行近似(即使这样,也不能准确表示)。

十六进制用于表示之前的数字,该数字p与IEEE 754格式中的有效数字相对应,因为它比二进制数更紧凑。IEEE
754二进制64的有效位数需要13个十六进制数字0x1.才能完整表示,这很多,但是以二进制52位数是必需的,这坦率地说是不切实际的。

十六进制的选择实际上有其缺点:由于这种选择,对于相同数字的几个等效表示并不总是容易识别为等效的。例如,0x1.3p10x2.6p0代表相同的数字,尽管它们的数字没有共同之处。以二进制形式,这两个符号将对应于0b1.0011p10b10.011p0,这将更容易视为等效。再举一个例子,3.14也可以表示为0xc.8f5c28f5c28f8p-2,很难看到与相同的数字0x1.91eb851eb851fp+1p如您在问题中所建议的,如果表示后的数字表示16的幂,则不会出现此问题,但是当C99标准化时,表示的唯一性不是目标:接近IEEE
754表示是。

2020-07-07