C语言 如何在C中表示内存中的FLOAT数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6910115/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to represent FLOAT number in memory in C
提问by Amit Singh Tomar
While reading a tutorial I came across how to represent Float number in memory. The tutorial had an example with a floating point number.
在阅读教程时,我遇到了如何在内存中表示浮点数。该教程有一个带有浮点数的示例。
float a=5.2 with below Diagram


Can anyone please tell how this 5.2 is converted in to binary and how it is represented in memory in above the above diagram?
谁能告诉我这个 5.2 是如何转换成二进制的,以及它是如何在上图中的内存中表示的?
回答by Rudy Velthuis
As was said, 5.2 is represented as a sign bit, an exponent and a mantissa. How do you encode 5.2?
如前所述,5.2 表示为符号位、指数和尾数。你如何编码5.2?
5 is easy:
5 很简单:
101.
The rest, 0.2 is 1/5, so divide 1.00000...(hex) by 5 and you get 0.3333333...(hex).
其余的 0.2 是 1/5,因此将1.00000...(hex) 除以 5 得到0.3333333...(hex)。
(This can be followed more easily if you consider one bit less: 0.FFFF...→ F / 5 = 3, so it is easy to see that 0.FFFF... / 5 = 0.33333.... That one missing bit doesn't matter when dividing by 5, so 1.0000... / 5 = 0.3333...too).
(如果你少考虑一点,这可以更容易地遵循:0.FFFF...→ F / 5 = 3,所以很容易看出0.FFFF... / 5 = 0.33333...。除以 5 时缺少的一位并不重要,所以1.0000... / 5 = 0.3333...也是如此)。
That should give you
那应该给你
0.0011001100110011001100110011...
Add 5, and you get
加5,你得到
101.00110011001100110011... exp 0 (== 5.2 * 2^0)
Now shift it right (normalize it, i.e. make sure the top bit is just before the decimal point) and adjust the exponent accordingly:
现在将它右移(标准化,即确保最高位正好在小数点之前)并相应地调整指数:
1.010011001100110011001100110011... exp +2 (== 1.3 * 2^2 == 5.2)
Now you only have to add the bias of 127 (i.e. 129 = 0b10000001) to the exponent and store it:
现在您只需要将 127 (即129 = 0b10000001)的偏差添加到指数并存储它:
0 10000001 1010 0110 0110 0110 0110 0110
Forget the top 1 of the mantissa (which is always supposed to be 1, except for some special values, so it is not stored), and you get:
忘记尾数的前 1(它总是应该是 1,除了一些特殊值,所以它不会被存储),你会得到:
01000000 10100110 01100110 01100110
Now you only have to decide little or big endian.
现在你只需要决定小端或大端。
This is not exactly how it works, but that is more or less what happens when a number like 5.2 is converted to binary.
这并不完全是它的工作原理,但这或多或少是将 5.2 之类的数字转换为二进制时会发生的情况。
回答by phimuemue
I think the diagram is not one hundret percent correct.
我认为该图表不是百分之一正确。
Floats are stored in memory as follows:
浮点数按如下方式存储在内存中:
They are decomposed into:
它们分解为:
- sign
s(denoting whether it's positive or negative) - 1 bit - mantissa
m(essentially the digits of your number - 24 bits - exponent
e- 7 bits
- 符号
s(表示它是正数还是负数)- 1 位 - 尾数
m(本质上是您号码的数字 - 24 位 - 指数
e- 7 位
Then, you can write any number xas s * m * 2^ewhere ^denotes exponentiation.
然后,您可以将任何数字写x为s * m * 2^ewhere^表示求幂。
5.2 should be represented as follows:
5.2 应表示如下:
0 10000001 01001100110011001100110
S E M
S=0denotes that it is a positive number, i.e. s=+1
S=0表示它是一个正数,即 s=+1
Eis to be interpreted as unsigned number, thus representing 129. Note that you must subtract 127 from Eto obtain the original exponent e = E - 127 = 2
E将被解释为无符号数,从而表示129。请注意,您必须减去 127E才能获得原始指数e = E - 127 = 2
Mmust be interpreted the following way: It is interpreted as a number beginning with a 1followed by a point (.) and then digits after that point. The digits after .are the ones that are actually coded in m. We introduce weights for each digit:
M必须按以下方式解释:它被解释为以 a 开头的数字,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)
Now you sum up the weights where the corresponding bits are set. After you've done this, you add 1(due to normalization in the IEEE standard, you always add 1 for interpreting M) and obtain the original m.
现在您总结了设置相应位的权重。完成此操作后,您添加1(由于 IEEE 标准中的规范化,您总是为解释添加 1 M)并获得原始m.
Now, you compute x = s * m * 2^eand get your original number.
现在,您计算x = s * m * 2^e并获得原始数字。
So, the only thing left is that in real memory, bytes might be in reverse order. That is why the number may not be stored as follows:
因此,唯一剩下的就是在实际内存中,字节可能处于相反的顺序。这就是为什么数字不能按如下方式存储的原因:
0 10000001 01001100110011001100110
S E M
but more the other way around (simply take 8-bit blocks and mirror their order)
但更多的是反过来(只需取 8 位块并镜像它们的顺序)
01100110 01100110 10100110 01000000
MMMMMMMM MMMMMMMM EMMMMMMM SEEEEEEE
回答by beren
The value is represented in memory in reverse order, but the confusing point may be that 5.2f is really represented as 5.1999998 due to the accuracy loss of the floating point values.
该值在内存中以相反的顺序表示,但令人困惑的一点可能是,由于浮点值的精度损失,5.2f 真的表示为 5.1999998。
回答by vijayanand1231
Representing 5.2 is very simple in binary logic:
用二进制逻辑表示5.2很简单:
8 4 2 1
5 -> 0 1 0 1
For a decimal number:
对于十进制数:
Take .2 and multiply by 2 (since it is represented in binary).
取 0.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
and so on...
等等...
After this step, take the value before the decimal point from output of the above steps:
在此步骤之后,从上述步骤的输出中取出小数点前的值:
.2 X 2 = 0.4 -> take 0 from this for representing in binary form
So the final o/p of 5.2 is:
所以 5.2 的最终 o/p 是:
0101.00110...
回答by user703016
Raw float 5.2:
原始浮点数 5.2:
01000000101001100110011001100110
^ sign bit
In memory, reverse byte order (as your diagram):
在内存中,反转字节顺序(如您的图表):
01100110011001101010011001000000
^ sign bit
回答by shivaji kapale
5.2
5.2
The number is stored in form of "Sign Bit,Exponent,Mantissa.
in binary form of 5 is 8 4 2 1so 0101and .2 is
数字以“符号位、指数、尾数的形式存储。以二进制形式 5 是 8 4 2 1这样0101,0.2 是
.2*2=.4 0
.4*2=.8 0
.8*2=1.6 1
and sign bit 0 Because Number is positive.
和符号位 0 因为 Number 是正数。
0 0101 001....
回答by JOBBINE
5.2 in binary 101.00110011...... ------> non normalized form 5.2 is .10100110011.... x 2^3 ------> explicit normal form 5.2 is .0100110011 x 2^3 in implicit normal form
5.2 二进制 101.00110011...... ------> 非标准化形式 5.2 是 .10100110011.... x 2^3 ------> 显式标准化形式 5.2 是 .0100110011 x 2^3隐式范式
here sign bit becomes 0 (because the number is positive) and exponent is seven bit so it is using excess 64 exponent notation so exponent will become 64+3 = 69 ie 1000101 and remaining will be mantissa (total 32bit - 7 exponent bit - 1 sign bit = 24 bit) 0100 1100 1100 1100 1100 1100
这里符号位变为 0(因为数字是正数)并且指数是 7 位,所以它使用了多余的 64 指数符号,所以指数将变成 64+3 = 69 即 1000101,剩下的将是尾数(总共 32 位 - 7 指数位 - 1符号位 = 24 位)0100 1100 1100 1100 1100 1100
In the above example sign bit is correct Excess 64 is not applied , so not normalized but ideally it should use implicit normalization Mantissa part in second byte if you apply implicit normalization the MSB '1' will not come .
在上面的示例中,符号位是正确的,未应用 Excess 64,因此未标准化,但理想情况下,如果应用隐式标准化,则应在第二个字节中使用隐式标准化尾数部分,MSB '1' 不会出现。
回答by Nahashon M
int a;
float b=5.2;
memcpy(&a, &b, 4);
printf("%d",a);
This gives 0100 0000 1010 0110 0110 0110 1000 0001 (1084647041)
这给出了 0100 0000 1010 0110 0110 0110 1000 0001 (1084647041)
回答by stacker
5.2 is represented as "01000000101001100110011001100110"
5.2 表示为“01000000101001100110011001100110”
Check the Converter Applet
检查转换器小程序
回答by Mojo Jojo
The conversion technique posted originally on the other website is shown unnecessarily complex (although it takes us to right answer) . For memory representation of 5.2 in memory:
最初发布在另一个网站上的转换技术显示出不必要的复杂(尽管它使我们正确答案)。对于内存中 5.2 的内存表示:
First convert it into simple binary system, which will give us 101.001100110011001100110011
首先将其转换为简单的二进制系统,这将给我们 101.001100110011001100110011
Now change it into scientific form : 1.01001100110011001100110011 x 10^2 .
现在将其更改为科学形式: 1.01001100110011001100110011 x 10^2 。
Now our sign bit is 0 as the number is positive
现在我们的符号位是 0 因为数字是正数
For exponent we need (127 + 2) upto 8 bits which gives us 10000001
对于指数,我们需要 (127 + 2) 最多 8 位,这给了我们 10000001
Fraction is 01001100110011001100110 . (23 bits) (Discarding the leading 1 of scientific form)
分数是 01001100110011001100110 。(23 位)(丢弃科学形式的前导 1)
=> the representation is
=> 表示是
0 10000001 0100 1100 1100 1100 1100 110
0 10000001 0100 1100 1100 1100 1100 110

