如何在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位
然后,你可以写任何数字x
为s * 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)