【发布时间】:2014-06-29 15:31:24
【问题描述】:
根据Swift 编程语言:
例如,0xFp2 表示 15 ⨉ 2^2,其计算结果为 60。 同样,0xFp-2 表示 15 ⨉ 2^(-2),其计算结果为 3.75。
为什么使用 2 而不是 16 作为指数的底?我本来希望0xFp2 == 15 * (16**2) 而不是0xFp2 == 15 * (2**2)
【问题讨论】:
标签: floating-point swift
根据Swift 编程语言:
例如,0xFp2 表示 15 ⨉ 2^2,其计算结果为 60。 同样,0xFp-2 表示 15 ⨉ 2^(-2),其计算结果为 3.75。
为什么使用 2 而不是 16 作为指数的底?我本来希望0xFp2 == 15 * (16**2) 而不是0xFp2 == 15 * (2**2)
【问题讨论】:
标签: floating-point swift
Swift 的浮点数十六进制表示法只是 notation introduced for C in the C99 standard 的一种变体,用于输入和输出(使用 printf %a 格式)。
该符号的目的是为了便于人类解释,同时让IEEE 754 representation 的位在一定程度上易于识别。 IEEE 754 表示使用以二为基数。因此,对于一个普通的浮点数,当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 binary64 数字的有效位需要0x1. 之后的 13 个十六进制数字才能完全表示,这很多,但在二进制中需要 52 位数字,这坦率地说是不切实际的。
选择十六进制实际上有其缺点:由于这种选择,同一数字的多个等价表示并不总是容易识别为等价的。例如,0x1.3p1 和 0x2.6p0 代表同一个数字,尽管它们的数字没有任何共同之处。在二进制中,这两个符号对应于0b1.0011p1 和0b10.011p0,这更容易被视为等效。再举一个例子,3.14也可以表示为0xc.8f5c28f5c28f8p-2,很难看出和0x1.91eb851eb851fp+1同一个数字。如果p 之后的数字代表 16 的幂,正如您在问题中所建议的那样,则不会存在此问题,但是当 C99 标准化时,表示的唯一性不是目标:与 IEEE 754 表示的接近度是。
【讨论】:
1 并且指定的位数足以“填写”类型?
long double;这就是我获得 3.14 的替代形式的方式)。允许输入方向的所有变体有其优势,例如对于整数 (0x7fffffff.0p0) 和表条目(如 stackoverflow.com/a/23726810/139746 中)