IEEE 754 Float 调试 - 从内存小端到实际浮点数

发布于 2024-11-28 21:30:08 字数 435 浏览 2 评论 0原文

我正在使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

美胚控场 2024-12-05 21:30:09

你正在打印出一些损坏的东西。我们只需要 32 位,它们是:

00 00 20 3E

二进制变量:

00000000 00000000 00100000 00111110

小尾数的逻辑值:

00111110 00100000 00000000 00000000

根据 IEEE:

0 01111100 01000000000000000000000
S E - 127  M - 1

所以现在很清楚:

  • 符号是 +1 (S = 0)
  • 指数是124 - 127 = -3
  • 尾数为 1.01b,即 5/4,

因此该值为 5/4 / 8 = 5/32 = 0.15625。

You are printing out something broken. We only need 32 bits, which are:

00 00 20 3E

Your variable in binary:

00000000 00000000 00100000 00111110

Logical value accounting for little endian:

00111110 00100000 00000000 00000000

According to IEEE:

0 01111100 01000000000000000000000
S E - 127  M - 1

So now it's clear:

  • the sign is +1 (S = 0)
  • the exponent is 124 - 127 = -3
  • the mantissaa is 1.01b, which is 5/4

So the value is 5/4 / 8 = 5/32 = 0.15625.

彩扇题诗 2024-12-05 21:30:09

您的值为十六进制 0x3E200000 或

0011 1110 0010 0000 0000 0000 0000 0000 

或重新排列:

s ----e--- ----------m------------
0 01111100 01000000000000000000000

sign_bit    = 0 (i.e. positive)
exponent    = 0x7C = 124 ---> subtract 127 to get -3
significand = 1 + 0.0100... = 1.0100... = 1*2^0 + 0*2^-1 + 1*2^-2 = 1.25

significand * 2^exponent = 1.25 * 2^-3 = 1.25 * 0.125 = 0.15625

Your value is hex 0x3E200000 or

0011 1110 0010 0000 0000 0000 0000 0000 

or rearranged:

s ----e--- ----------m------------
0 01111100 01000000000000000000000

sign_bit    = 0 (i.e. positive)
exponent    = 0x7C = 124 ---> subtract 127 to get -3
significand = 1 + 0.0100... = 1.0100... = 1*2^0 + 0*2^-1 + 1*2^-2 = 1.25

significand * 2^exponent = 1.25 * 2^-3 = 1.25 * 0.125 = 0.15625
再浓的妆也掩不了殇 2024-12-05 21:30:09

IEEE 浮点的基本格式基于四字节
value,这样显示的话更容易分析。在那
在这种情况下,最高位是指数,接下来的 8 位是指数(超过
127),其余为尾数。最简单的解释方法是
可能是为了显示将访问单独字段的 C++ 代码:

double d;
// ...
uint32_t const* p = reinterpret_cast<uint32_t const*>( &d );
bool isNegative = (*p & 0x80000000) != 0;
int exp = ((*p & 0x78000000) >> 23) - 127;
int mantissa = (*p & 0x07FFFFFF) | 0x08000000 ;

尾数应该在 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:

double d;
// ...
uint32_t const* p = reinterpret_cast<uint32_t const*>( &d );
bool isNegative = (*p & 0x80000000) != 0;
int exp = ((*p & 0x78000000) >> 23) - 127;
int mantissa = (*p & 0x07FFFFFF) | 0x08000000 ;

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.

[旋木] 2024-12-05 21:30:08

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.

enter image description here

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文