IEEE 754 Float 调试 - 从内存小端到实际浮点数
我正在使用 VS2008 测试 IEEE 754 浮动格式,使用下面的示例:
int main(int argc, char *argv[])
{
float i = 0.15625;
}
我将 &i 放入 VS2008 手表,我看到地址是 0x0012FF60,我可以从内存调试窗口看到地址的内容是 00 00 20 3e,如下所示:
0x0012FF60 00 00 20 3e cc cc cc cc
顺便说一句,我有 IEEE754 浮点格式的基本知识,并且我知道 IEEE 754 浮点格式由三个字段组成:符号位、指数和分数。小数是没有最高有效位的有效数。
但是我如何精确计算从小端 00 00 20 3e 到 0.15625 ?
非常感谢
I am testing IEEE 754 floating format with VS2008 using the example below:
int main(int argc, char *argv[])
{
float i = 0.15625;
}
I put &i to the VS2008 watch and I see the address is 0x0012FF60 and I can see address's content is 00 00 20 3e from Memory debug window, see below:
0x0012FF60 00 00 20 3e cc cc cc cc
BTW I have the basic knowledge of IEEE754 floating format and I know IEEE 754 floating format consist of three fields: sign bit, exponent, and fraction. The fraction is the significand without its most significant bit.
But how did I calcuate exactly from little endian 00 00 20 3e to 0.15625 ?
Many thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
你正在打印出一些损坏的东西。我们只需要 32 位,它们是:
二进制变量:
小尾数的逻辑值:
根据 IEEE:
所以现在很清楚:
S = 0
)因此该值为 5/4 / 8 = 5/32 = 0.15625。
You are printing out something broken. We only need 32 bits, which are:
Your variable in binary:
Logical value accounting for little endian:
According to IEEE:
So now it's clear:
S = 0
)So the value is 5/4 / 8 = 5/32 = 0.15625.
您的值为十六进制 0x3E200000 或
或重新排列:
Your value is hex 0x3E200000 or
or rearranged:
IEEE 浮点的基本格式基于四字节
value,这样显示的话更容易分析。在那
在这种情况下,最高位是指数,接下来的 8 位是指数(超过
127),其余为尾数。最简单的解释方法是
可能是为了显示将访问单独字段的 C++ 代码:
尾数应该在 24 上方有一个隐式小数位
位(但我不知道如何将其表示为整数:-))。
如果你拥有的只是一个字节序列,那么你必须组装它们,
根据字节顺序,然后应用上面的。
编辑:继 Rudy Velthuis 指出我的错误之后,常量值已得到纠正。
The basic format of an IEEE floating point is based on a four byte
value, and it is simpler to analyse if you display it as such. In that
case, the top bit is the exponent, the next 8 the exponent (in excess
127), and the rest the mantissa. The simplest way to explain it is
probably to show the C++ code which would access the separate fields:
The mantissa should have an implicit decimal place just above the 24
bits (But I don't know how to represent this as an integer:-)).
If all you have is a sequence of bytes, you have to assemble them,
according to the byte order, and then apply the above.
Edited: the constant values have been corrected, following up on Rudy Velthuis' pointing out my error.
32 位浮点数的内存布局(请参阅 http://en.wikipedia.org/wiki/Single_ precision ) 在大端机器上。
小端机器(例如 x86)只是交换字节对,“cc”是未使用的位内存使 32 位浮动到调试器编辑显示的 64 位值
:
请记住,指数是有符号的(二进制补码),并且由于 0.15625 小于 1,因此指数为负数)
值 = 符号 * 2^exp * 尾数。
0x3e = 0011 1110
0x20 = 0010 0000
由于符号位,我们必须将它们打乱
指数 = 0111 1100 = -3
尾数 = 0100 0000 = 1 + 0.25 (假设第一位之前的那个)
即 0.15625 = +1 * 2^(-3) * 1.25
Memory layout of a 32bit float ( see http://en.wikipedia.org/wiki/Single_precision ) on a big endian machine.
A little endian machine (eg. x86) simply swaps pairs of bytes, the 'cc' are unused bits of memory to make the 32bit float upto a 64bit value being displayed by the debugger
edit:
Remember the exponent is signed (twos complement) and since 0.15625 is less than 1 the exponent is negative)
value = sign * 2^exp * mantissa.
0x3e = 0011 1110
0x20 = 0010 0000
Because of the sign bit we have to shuffle these along one so
exponent = 0111 1100 = -3
mantissa = 0100 0000 = 1 + 0.25 ( the one before the first place is assumed)
ie 0.15625 = +1 * 2^(-3) * 1.25