Floating point 32位IEEE 754单精度浮点到十六进制

Floating point 32位IEEE 754单精度浮点到十六进制,floating-point,hex,ieee-754,Floating Point,Hex,Ieee 754,我已经学会了如何将数字转换成浮点(在二进制、八进制和十六进制的基础上),并且知道如何将数字转换成浮点 然而,在查看给我的工作表时,我遇到了以下问题: 使用32位IEEE 754单精度浮点显示-12.13的十六进制表示。 我已经尝试查看了我拥有的资源,但仍然不知道如何回答上述问题。给出的答案是0xc142147b 编辑:很抱歉没有澄清,但我想知道如何手动完成此操作,而不是对其进行编码。-12.13必须先转换为二进制,然后转换为十六进制。让我们或多或少像glibc库那样,只使用纸笔和Windows计

我已经学会了如何将数字转换成浮点(在二进制、八进制和十六进制的基础上),并且知道如何将数字转换成浮点

然而,在查看给我的工作表时,我遇到了以下问题:

使用32位IEEE 754单精度浮点显示-12.13的十六进制表示。

我已经尝试查看了我拥有的资源,但仍然不知道如何回答上述问题。给出的答案是0xc142147b


编辑:很抱歉没有澄清,但我想知道如何手动完成此操作,而不是对其进行编码。

-12.13
必须先转换为二进制,然后转换为十六进制。让我们或多或少像glibc库那样,只使用纸笔和Windows计算器

移除标志,但记住我们有一个:
12.13

有效位(或尾数) 整数部分,
12
很简单:
C
(十六进制)

分数部分,
0.13
有点棘手<代码>0.13是
13/100
。我使用Windows计算器(程序员模式,十六进制)并将
13
(十六进制
D
)向左移位32(*)位:
D00000000
。将其除以
100
(十六进制
64
)得到:
2147AE14
十六进制

因为我们需要一个小于1的值,所以我们再次右移32位,得到:
0.2147AE14

现在在左边添加整数部分:
C.2147AE14

尾数只需要24位,所以我们取整:
C.2147B
-->
C2147B

现在必须对其进行规范化,因此二进制点向左移动3位(当然,这些位保持不变)。指数(最初为0)相应地增加了3,所以现在是3

现在可以删除隐藏位:
42147B
(现在是23个低位)

现在可以将其转换为32位值:
0x0042147B

指数和符号 现在让我们看一下指数:
3
+十六进制偏差
7F
=hex
82
,或
1000 0010
二进制

在左侧添加符号位:
1 1000 0010
。重新组合:
1100 0001 0
C10

当然,这些是顶部位,因此我们将其转换为完整32位的
0xC1000000

“按位或”两部分 这就是你想要的价值



(*)32位,因此我有足够多的位,以便以后能够正确地进行舍入。

-12.13
必须转换为二进制,然后转换为十六进制。让我们或多或少像glibc库那样,只使用纸笔和Windows计算器

移除标志,但记住我们有一个:
12.13

有效位(或尾数) 整数部分,
12
很简单:
C
(十六进制)

分数部分,
0.13
有点棘手<代码>0.13是
13/100
。我使用Windows计算器(程序员模式,十六进制)并将
13
(十六进制
D
)向左移位32(*)位:
D00000000
。将其除以
100
(十六进制
64
)得到:
2147AE14
十六进制

因为我们需要一个小于1的值,所以我们再次右移32位,得到:
0.2147AE14

现在在左边添加整数部分:
C.2147AE14

尾数只需要24位,所以我们取整:
C.2147B
-->
C2147B

现在必须对其进行规范化,因此二进制点向左移动3位(当然,这些位保持不变)。指数(最初为0)相应地增加了3,所以现在是3

现在可以删除隐藏位:
42147B
(现在是23个低位)

现在可以将其转换为32位值:
0x0042147B

指数和符号 现在让我们看一下指数:
3
+十六进制偏差
7F
=hex
82
,或
1000 0010
二进制

在左侧添加符号位:
1 1000 0010
。重新组合:
1100 0001 0
C10

当然,这些是顶部位,因此我们将其转换为完整32位的
0xC1000000

“按位或”两部分 这就是你想要的价值



(*)32位,因此我有足够多的位,以便稍后能够正确地进行舍入。

要对浮点数进行编码,我们必须将其重写为(-1)s 2e 1.m 并以32位对不同部分进行编码,如下所示

(来自)

  • 第一位是符号s:0表示+和1表示-

  • 以下8位是移位指数e+127

  • 23最后一位是尾数(m)的小数部分

困难的部分是将尾数转换为二进制。对于一些数字来说,这很容易。例如,5.75=4+1+1/2+1/4=22+20+2-1+2-2=101.11=1.0111×22

对于其他数字(如您的),则更难。解决方案是将数字乘以2,直到找到一个整数,或者超过代码中的总位数(23+1)

我们可以为您的电话号码:

 12.13 =       12.13 2^-0
       =       24.26 2^-1
       =       48.52 2^-2
       =       97.04 2^-3
       =      194.08 2^-4
       =      388.16 2^-5
       =      776.32 2^-6
       =     1552.64 2^-7
       =     3105.28 2^-8
       =     6210.56 2^-9
       =    12421.12 2^-10
       =    24842.24 2^-11
       =    49684.48 2^-12
       =    99368.96 2^-13
       =   198737.92 2^-14
       =   397475.84 2^-15
       =   794951.69 2^-16
       =  1589903.38 2^-17
       =  3179806.75 2^-18
       =  6359613.50 2^-19
       = 12719227.00 2^-20
下一次迭代将导致一个大于2^24(~16M)的数字,我们可以停止

尾数代码很容易(但有点长)使用常用方法手动转换为二进制,其代码为0xc2147b。如果我们在223位置提取1处的前导位并将其放在“点”的左侧,则尾数=1.42147b×223(其中小数部分限制为23位)。因为我们必须用初始数乘以220才能得到这个值,我们最终得到

mant=1.42147b×23

指数是3,代码是3+127=130

exp=130d=0x82

因为这个数字是负数

符号=1

我们只需要,抑制尾数的整数部分(隐藏位),并连接这些数字以获得最终值0xc142147b

(当然,我使用了一个程序来生成这些数字。如果
 12.13 =       12.13 2^-0
       =       24.26 2^-1
       =       48.52 2^-2
       =       97.04 2^-3
       =      194.08 2^-4
       =      388.16 2^-5
       =      776.32 2^-6
       =     1552.64 2^-7
       =     3105.28 2^-8
       =     6210.56 2^-9
       =    12421.12 2^-10
       =    24842.24 2^-11
       =    49684.48 2^-12
       =    99368.96 2^-13
       =   198737.92 2^-14
       =   397475.84 2^-15
       =   794951.69 2^-16
       =  1589903.38 2^-17
       =  3179806.75 2^-18
       =  6359613.50 2^-19
       = 12719227.00 2^-20
#include <stdio.h>
int main () {
  float f=-12.13;
  int sign=(f<0.0);
  float fmantissa;
  fmantissa = (f<0.0?-f:f) ; // abs value of f
  int   e = 0 ;              // the raw exponent
  printf("%2.2f = %11.2f 2^-%d\n",f,fmantissa,e);
  while (fmantissa<=(1<<23)){
    e++; fmantissa*=2.0;
    printf("       = %11.2f 2^-%d\n",fmantissa,e);
  }

  // convert to int
  int mantissa=fmantissa;
  //and suppress hidden bit in mantissa
  mantissa &= ~(1<<23) ;

  // coded exponent
  int exp=127-e+23;

  printf("sign: %d exponent: %d mantissa: 1.%x\n",sign, exp, mantissa);
  //final code
  int fltcode = (sign << 31) | (exp << 23) | mantissa;

  printf("0x%x\n",fltcode);
}