繁体   English   中英

使用 C 语言的十六进制浮点表示

[英]Floating Point Representation in Hexadecimal using C Langauge

我输入了以下 C 代码:

typedef unsigned char* byte_pointer;

void show_bytes(byte_pointer start, size_t len) 
{
  int i;
  for (i = 0; i < len; i++)
  printf(" %.2x", start[i]);
  printf("\n");
}

 void show_float(float x) 
  {
       show_bytes((byte_pointer) &x, sizeof(float));
  }
 void main()
    {
         float f = 3.9;
         show_float(f);
    }

这段代码的输出是:输出:0x4079999A

手动计算1.1111001100110011001100 x 2 幂 1

男:1111001100110011001100

E: 1 + 127 = 128(d) = 10000000(b)

最后位: 01000000011110011001100110011000

十六进制:0x40799998

尽管是 8,但为什么显示最后一个 A。

根据手动计算,十六进制的答案应该是:输出:0x40799998

那些未公开的人工计算肯定是错误的。 正确的结果是 4079999A 16

在通常用于float 、IEEE-754 binary32 或“单精度”的格式中,数字表示为一个整数,其大小小于 224,乘以一定范围内的 2 的幂。 (浮点表示通常以其他形式描述,例如符号、第一个数字后带有小数点的 24 位二进制有效数和 2 的幂。这些形式在数学上是等效的。)

这种形式中最接近 3.9 的两个数字是 16,357,785•2 −23和 16,357,786•2 −23 它们分别是 3.8999998569488525390625 和 3.900000095367431640625。 将它们排列起来,我们可以看到后者更接近 3.9:

3.8999998569488525390625
3.9000000000000000000000
3.9000000953674316406250

因为前者在小数点后第七位相差1.5,而后者在小数点后第八位相差约9.5。

因此,从 3.9 到这种float格式的最佳转换会产生 16,357,786•2 −23 在十六进制中, 16,357,786 是 F9999A 16 在将表示编码为float的位时,有效数的低 23 位被放入主要有效数字段。 低 23 位是 79999A 16 ,这就是我们应该在主要有效数字段中看到的。

另请注意,我们可以很容易地看到 3.9 的二进制文件是11.1110011001100110011001 1001100110011001100110… 2 粗体标记了适合float有效数的 24 位。 紧随其后的是 1001...,我们可以看到它应该四舍五入,因为它超过了前一位的一半,因此有效数的最后四位应该是 1010。

(还要注意,好的 C 实现将源文本中的数字转换为最接近的可表示数字,尤其是对于没有很多十进制数字的数字,但 C 标准不要求这样做。它说“对于十进制浮点常量,以及十六进制浮点常量,当FLT_RADIX不是 2 的幂,结果要么是最近的可表示值,要么是紧邻最近可表示值的较大或较小的可表示值,以实现定义的方式选择。但是,问题 40799998 16 中显示的编码, 不适用于相邻的可表示值 40799999 16和 4079999A 16 。它比任何一个都更远。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM