1

考虑这个简单的代码(t0.c):

#include <stdio.h>
#include <float.h>

#if DBL_HAS_SUBNORM == 1
double d = 0x23d804860c09bp-1119;

int main(void)
{
    printf("%a\n", d);
    return 0;
}
#endif

调用和输出:

# host: CPU: Intel, OS: Windows 10
$ gcc t0.c -std=c11 && ./a.exe
0x1.2p-1070

# host: CPU: Intel, OS: Windows 10
$ clang t0.c -std=c11 && ./a.exe
0x1.2p-1070

# host: CPU: Intel, OS: Linux
$ gcc t0.c -std=c11 && ./a.out
0x0.0000000000012p-1022

# host: CPU: Intel, OS: Linux
$ clang t0.c -std=c11 && ./a.out
0x0.0000000000012p-1022

问题:对于转换说明符%a,如何:

  • 选择了十六进制浮点常量的确切格式,并且
  • 这个十六进制浮点常数的参数选择?

例如,为什么0x1.2p-1070而不是0x0.0000000000012p-1022(或其他变体)(反之亦然)?

4

1 回答 1

2

C 允许在细节上有一定的自由度

表示浮点数的双精度参数转换为 [-]0xh.hhhhp±d 样式,其中在小数点字符及其后的十六进制位数等于精度;如果缺少精度并且 FLT_RADIX 是 2 的幂,则精度足以精确表示该值 ...(更多关于 base 10 编码、Inf 和 NaN)
C2xdr § 7.21.6.1 8

我看到的显着变化是第一个h数字是否'0'-'F''0'-'1'.


为什么是 0x1.2p-1070 而不是 0x0.0000000000012p-1022

对于正常值,前导数字指定为非零。然而,由于 OP 的值看起来低于正常值,因此两者都可以接受。它是未指定的。

于 2021-06-02T15:01:07.237 回答