32位IEEE 754单精度浮点为十六进制(32-bit IEEE 754 single preci

2019-09-27 13:38发布

我已经学会了如何将数字转换为浮点(二进制,八进制和十六进制的顶部),并知道如何将数字转换为浮点。

然而,同时通过工作找他们给了我,我也遇到过以下问题:

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

我试图寻找我所拥有的资源,但还是无法弄清楚如何回答以上。 给出的答案是0xc142147b。

编辑:对不起,不澄清,但我想知道如何让手工完成这件事编码它代替。

Answer 1:

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

取出迹象,但还记得我们有一个: 12.13

有效数(或尾数)

的整数部分, 12是容易的: C (十六进制)

小数部分, 0.13是有点麻烦。 0.1313/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 =十六进制82 ,或1000 0010二进制文件。

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

当然,这些都是顶位,所以我们把它转换成0xC1000000的完整的32位

“按位或”两部分

0xC100000 | 0x0042147B = 0xC142147B

这是你想要的值。


(*)32位,所以我有足够多的位更能够正确圆,以后。



Answer 2:

为了译码一个浮点数,我们必须重写为(-1) 2ë1.M并如下在32位的不同部分进行编码

(从https://en.wikipedia.org/wiki/Single-precision_floating-point_format )

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

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

  • 23最后的位为的尾数(M)的小数部分

难的是尾数转换为二进制。 对于一些数字,很容易。 例如,5.75 = 4 + 1 + 1/2 + 1/4 = 2 2 2 0 2 -1 +2 -2 = 101.11 = 1.0111×2 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。 如果我们在提取1在2位23中的引导位,并把它留的“点”,我们有尾数= 1.42147b×2 23(其中分数部分被限制为23位)。 正如我们所用的初始数量由2 20相乘得到这个值,我们终于等来了

MANT = 1.42147b×2 3

所以指数是3,它的代码是3 + 127 = 130

EXP = 130 d =为0x82

并作为数是负的

签= 1

我们只需要,以抑制尾数(隐藏位)的整数部分,来串联这个数字让0xc142147b的终值

(当然,我用一个程序来生成这些数字。如果有兴趣,这里是C代码)

#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);
}


文章来源: 32-bit IEEE 754 single precision floating point to hexadecimal