【问题标题】:Floating Point Representation in Hexadecimal using C Langauge使用 C 语言以十六进制表示浮点数
【发布时间】:2021-12-18 14:29:34
【问题描述】:

我输入了以下 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

为什么最后一个 A 显示为 8。

【问题讨论】:

  • 如果你有 float f = 3.9f; 会发生什么?您的 3.9double 值。请注意,3.9 无法精确转换为有限二进制浮点表示,因此实现细节将涵盖近似值是向上舍入还是向下舍入。
  • 最好不要typedef指针。
  • @WeatherVane:应该不会有太大变化。双 3.9 值的浮点截断很可能是浮点值 3.9f。我假设多精度表示应该是0x4079999999999...。这通常四舍五入到更接近的可表示浮点值0x4079999A。问题是哪个手动计算会导致0x40799998...
  • @SergeBallesta 是的,在实践中我发现没有区别。一条已删除的评论质疑人工计算的依据;)

标签: c floating-point hex


【解决方案1】:

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

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

在通常用于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 是 F9999A16。在将表示编码为float 的位时,有效数字的低 23 位被放入主要有效数字字段。低 23 位是 79999A16,这就是我们应该在主有效位字段中看到的内容。

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

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

【讨论】:

    猜你喜欢
    • 2012-08-10
    • 2018-11-13
    • 2022-01-05
    • 2023-04-06
    • 2011-05-31
    • 2013-07-14
    • 1970-01-01
    • 1970-01-01
    • 2019-04-07
    相关资源
    最近更新 更多