For example,0xFp2 represents 15 ⨉ 2^2,which evaluates to 60.
Similarly,0xFp-2 represents 15 ⨉ 2^(-2),which evaluates to 3.75.
为什么2用作指数的基数而不是16?我原以为0xFp2 == 15 *(16 ** 2)而不是0xFp2 == 15 *(2 ** 2)
该符号的目的是易于被人类解释并且让IEEE 754 representation的位有些可识别. IEEE 754表示使用基数2.因此,对于正常的浮点数,当p之前的数字在1和2之间时,p之后的数字直接是IEEE 754表示的指数字段的值.这符合人类可读性和与位表示的紧密性的双重目标:
$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号的有效位数在0x1之后需要13个十六进制数字.完全代表,这是很多,但二进制52位数将是必需的,这是坦率的不切实际.
十六进制的选择实际上有它的缺点:由于这种选择,相同数字的几个等价表示并不总是容易识别为等价.例如,0x1.3p1和0x2.6p0表示相同的数字,尽管它们的数字没有任何共同之处.在二进制中,两个符号将对应于0b1.0011p1和0b10.011p0,这将更容易看作等效.再举一个例子,3.14也可以表示为0xc.8f5c28f5c28f8p-2,这很难看作与0x1.91eb851eb851fp 1相同的数字.如果p之后的数字表示16的幂,则该问题不存在,正如你在你的问题中所建议的那样,但当C99标准化时,表示的单一性并不是一个目标:接近IEEE 754表示.