如何在C中表示内存中的FLOAT编号

在阅读教程时,我遇到了如何在内存中表示浮点数。 教程有一个浮点数的例子。

float a=5.2 with below Diagram 

在这里输入图像描述

任何人都可以告诉如何将这个5.2转换成二进制文件,以及它如何在上面的图表中的内存中表示?

如前所述,5.2代表符号位,指数和尾数。 你如何编码5.2?

5很容易:

 101. 

其余的0.2是1/5,所以除以1.00000... (hex)5,得到0.3333333... (hex)。

(如果考虑less一点,可以更容易地跟随: 0.FFFF...F / 5 = 3 ,所以很容易看出0.FFFF... / 5 = 0.33333...这个当除以5时丢失位并不重要,所以1.0000... / 5 = 0.3333...也是)。

这应该给你

 0.0011001100110011001100110011... 

加5,就可以了

 101.00110011001100110011... exp 0 (== 5.2 * 2^0) 

现在将其右移(标准化,即确保顶端位于小数点之前)并相应地调整指数:

 1.010011001100110011001100110011... exp +2 (== 1.3 * 2^2 == 5.2) 

现在你只需要把127的偏差(即129 = 0b10000001 )加到指数上并存储它:

 0 10000001 1010 0110 0110 0110 0110 0110 

忘记尾数的前1(总是应该是1,除了一些特殊的值,所以它不被存储),你会得到:

 01000000 10100110 01100110 01100110 

现在你只需要决定是小的还是大的。

这不是完全如何工作,但是当像5.2这样的数字被转换成二进制时,或多或less会发生什么。

我认为该图不是一个正确的百分比。

浮游物存储在内存中如下:

他们被分解成:

  • 标志s (表示是正数还是负数) – 1位
  • 尾数m (基本上是你的号码的数字 – 24位
  • 指数e – 7位

然后,你可以写任何数字xs * m * 2^e其中^表示指数。

5.2应表示如下:

 0 10000001 01001100110011001100110 SEM 

S=0表示它是一个正数,即s=+1

E被解释为无符号数,代表129 。 请注意,您必须从E减去127以获得原始指数e = E - 127 = 2

M必须按以下方式解释:它被解释为以1开头的数字,然后是点( . ),然后是该点之后的数字。 后面的数字. 是那些实际编码为m 。 我们介绍每个数字的权重:

 bits in M: 0 1 0 0 1 ... weight: 0.5 0.25 0.125 0.0625 0.03125 ... (take the half of the previous in each step) 

现在您总结了设置相应位的权重。 完成这个之后,你加1 (由于在IEEE标准中的规范化,你总是加1来解释M )并且获得原始的m

现在,你计算x = s * m * 2^e并且得到你的原始数字。

所以,唯一剩下的就是在实际内存中,字节可能是相反的顺序。 这就是为什么该号码可能不被存储如下:

 0 10000001 01001100110011001100110 SEM 

但更多相反(简单地采取8位块和镜像他们的顺序)

 01100110 01100110 10100110 01000000 MMMMMMMM MMMMMMMM EMMMMMMM SEEEEEEE 

该值以相反的顺序在内存中表示,但令人困惑的是,由于浮点值的精度损失,5.2f实际上表示为5.1999998。

原始浮动5.2:

 01000000101001100110011001100110 ^ sign bit 

在内存中,反转字节顺序(如图):

 01100110011001101010011001000000 ^ sign bit 

在二进制逻辑中表示5.2非常简单:

  8 4 2 1 5 -> 0 1 0 1 

对于十进制数字:

以.2和乘以2(因为它以二进制表示)。

 .2 X 2 = 0.4 -> take the value after the decimal point, don't take the value before the decimal point .4 X 2 = 0.8 .8 X 2 = 1.6 .6 X 2 = 1.2 .2 X 2 = 0.4 

等等…

在此步骤之后,从上述步骤的输出中取小数点前的值:

 .2 X 2 = 0.4 -> take 0 from this for representing in binary form 

所以最后的5.2是:

 0101.00110... 

5.2

该号码以“Sign Bit,Exponent,Mantissa”的forms存储,二进制forms为8 4 2 1因此0101和.2是

 .2*2=.4 0 .4*2=.8 0 .8*2=1.6 1 

和符号位0因为数字是正的。

 0 0101 001.... 

5.2二进制101.00110011 …… ——>非规范化forms5.2是.10100110011 …. x 2 ^ 3 ——>显式规范forms5.2是.0100110011 x 2 ^ 3以隐式的正常forms

这里符号位变成了0(因为数字是正的)并且指数是7位,所以它使用了超过64的指数符号,所以指数将变成64 + 3 = 69,即1000101,剩下的将是尾数(总计32位-7指数位-1符号位= 24位)0100 1100 1100 1100 1100 1100

在上面的例子中,符号位是正确的。过量的64没有被应用,所以没有被标准化,但是理想情况下它应该使用隐式标准化尾数部分在第二个字节,如果你应用隐式标准化,MSB'1'不会来。

5.2表示为“01000000101001100110011001100110”

检查转换器小程序

原本在其他网站上发布的转换技术显示为不必要的复杂(尽pipe我们需要正确的答案)。 对于内存中5.2的内存表示:

首先将其转换成简单的二进制系统,这将给我们101.001100110011001100110011

现在改成科学forms:1.01001100110011001100110011 x 10 ^ 2。

现在我们的符号位是0,因为数字是正数

对于指数我们需要(127 + 2)高达8位,给我们10000001

分数是01001100110011001100110。 (23位)(摒弃科学forms的领先1)

=>表示是

0 10000001 0100 1100 1100 1100 1100 110

下面两个参考帮助我理解了二进制格式的IEE 754浮点数编码,

~juy9/142/slides/L3-FP_Representation.pdf

http://en.wikipedia.org/wiki/Single-precision_floating-point_format

 int a; float b=5.2; memcpy(&a, &b, 4); printf("%d",a); 

这给出0100 0000 1010 0110 0110 0110 1000 0001(1084647041)