我想了解数字(双精度)如何在 bash 中表示,以及当我在 bash 中以十六进制格式打印数字时会发生什么。
根据 IEEE 754 标准,double 应由 64 位表示:52 位(13 个十六进制数)表示有效数,11 位表示指数,1 位表示符号。
为了检查它,我编写了一个简单的 C 程序,将十六进制转换为十进制(使用 printf)。
include <stdio.h>
int main(int argc, char **argv)
{
printf("hex read = %40.24a\n", 0x1.000010C6F7A0B5E1Fp+0);
}
用 gcc 4.2.1 编译,我得到
hex read = 0x1.000010c6f7a0b00000000000p+0
从这个结果我得出结论,正如我所期望的那样,有效位由 13 个十六进制数字 000010c6f7a0b 定义。
现在我转向 bash 并使用以下脚本:
#!/bin/bash
echo "hex read = 0x"$1
printf "hex =%80.70a\n" "0x"$1
printf "hex -> dec=%80.70f\n" `echo "0x"$1`
GNU 重击 3.2.48
$ bash hex2dec 1.000010C6F7A0B5E1F
hex read = 0x1.000010C6F7A0B5E1F
hex = 0x1.000010c6f7a0b000000000000000000000000000000000000000000000000000000000p+0
hex -> dec= 1.0000009999999999177333620536956004798412322998046875000000000000000000
所以一切都按我的预期工作:13 个十六进制数字定义了数字的有效位。
GNU 重击 4.1.5
$ bash hex2dec 1.000010C6F7A0B5E1F
hex read = 0x1.000010C6F7A0B5E1F
hex = 0x8.00008637bd05af10000000000000000000000000000000000000000000000000000000p-3
hex -> dec= 1.0000009999999999993737856418540843606024282053112983703613281250000000
这不是我所期望的!
问题 1为什么在 GNU bash 4.1.5 中双精度数由 16 个十六进制数字表示(而不是根据 IEEE 754 的 13 个)?
问题 2为什么 printf "%a" 在不同的 bash 版本中以不同的格式表示十六进制数(bash 3.2.48 0x1.hh...hp+d 和bash 4.1.5 0xh.hh...hp+d?) . printf 不应该在两个 bash 版本中遵循相同的标准并由http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html重新定义吗?