-
-
[原创]以前写的浮点数在计算机内部存储的笔记
-
发表于:
2009-11-8 21:20
12387
-
浮点数在电脑的存储形式,
一、浮点数
浮点数存储由三个部分组成:符号s,指数部分e,尾数部分m。
_____________________________________________________
| 符号s部分 | 指数e部分 |尾数m部分 |
| 1位:0正,1负。 | 8位 |23位 |
------------------------------------------------------------------------------
符号s部分:最高位表示数据的正负,0表示正数,1表示负数。
指数e部分:表示数据以2为底的幂,指数采用偏移码表示,偏移基数是127,8位的指数除了全0,全1外有1~254个编码表示-126~127。
有效数字部分:表示数据小数点后的有效数字。23位的有效数字位,当然以上的位数都是以单精度的浮点数为例,双精度浮点数的数据格式是64位的,符号位1位,指数占11位,尾数占52位。
二、浮点数存储转换
浮点数存储形式转换成十进制数的公式:
S:是符号位。
m:是有效数字尾部。
e:是指数。
指数是用偏移码表示,偏移基数是127,所以2的指数是e-127。
实例分析:49E48E68H= 0100 1001 1110 0100 1000 1110 0110 1000B
把它分成三个部分:符号,指数和有效数字部分
49E48E68H = 0 100 1001 1 110 0100 1000 1110 0110 1000B
其中符号s是0。
指数部分100 1001 1,转化成十进制是128+16+2+1=147,e=147。
有效数字部分:110 0100 1000 1110 0110 1000。十进制形式:m=0.78559589385986328125
把以上上几部分带入转化公式中,这样就能求出该浮点数的十进制数表示:
==1872333
用一个实例程序来验证十进制的实数和电脑内部浮点数存储形式的关系
实例【程序】
main()
{
float a,b,c;
a=1;
b=1.2;
c=100.25;
printf("a=%f,b=%f,c=%f",a,b,c);
}
汇编代码:
00401000 /$ 55 push ebp ; 主函数
00401001 |. 8BEC mov ebp, esp
00401003 |. 83EC 0C sub esp, 0C ; 三个变量占12字节
00401006 |. C745 FC 00008>mov dword ptr [ebp-4], 3F800000 ; 变量a赋值
0040100D |. C745 F8 9A999>mov dword ptr [ebp-8], 3F99999A ; 变量b赋值
00401014 |. C745 F4 0080C>mov dword ptr [ebp-C], 42C88000 ; 变量c赋值
0040101B |. D945 F4 fld dword ptr [ebp-C]
0040101E |. 83EC 08 sub esp, 8
00401021 |. DD1C24 fstp qword ptr [esp]
00401024 |. D945 F8 fld dword ptr [ebp-8]
00401027 |. 83EC 08 sub esp, 8
0040102A |. DD1C24 fstp qword ptr [esp]
0040102D |. D945 FC fld dword ptr [ebp-4]
00401030 |. 83EC 08 sub esp, 8
00401033 |. DD1C24 fstp qword ptr [esp]
00401036 |. 68 30804000 push 00408030 ; ASCII "a=%f,b=%f,c=%f"
0040103B |. E8 07000000 call 00401047
00401040 |. 83C4 1C add esp, 1C
00401043 |. 8BE5 mov esp, ebp
00401045 |. 5D pop ebp
00401046 \. C3 retn
在c语言中有这三个赋值语句 a=1;
b=1.2;
c=100.25;
那么在汇编中必然将十进制的1转化成浮点存储形式的值给变量a赋值,
将十进制的1.2转化成浮点存储形式的值给变量b赋值,
将十进制的100.25转化成浮点存储形式的值给变量c赋值。
1转化浮点存储形式:s=0;
e=127d=01111111;
m=0
所以1浮点存储形式是 0 011 1111 1 000 0000 0000 0000 0000 0000
用十六进制表示: 3 F 8 0 0 0 0 0
所以将1赋给浮点型变量a,在电脑内部就是将3F800000赋给变量a;
我们在汇编代码00401006 处果然有一条mov dword ptr [ebp-4], 3F800000命令,这就验证了我们做的转化是正确的。
1.2转化浮点存储形式,先将1.2转化成二进制:1.2d=1.001 1001 1001 1001 1001 1001b
在二进制中就可以观察出s=0;
e=127d=01111111;
m=0.2d=001 1001 1001 1001 1001 1001b
所以1.2的浮点存储形式是:0 011 1111 1 001 1001 1001 1001 1001 1001
用十六进制表示: 3 F 9 9 9 9 9 9
所以将1.2赋给浮点型变量b,在电脑内部就是将3F99999A赋给变量b;
我们在汇编代码0040100D处果然有一条mov dword ptr [ebp-8], 3F99999A命令,这就验证了我们做的转化是正确的。
100.25转化浮点存储形式,先将100.25转化成二进制:100.25d=0110 0100.01B=1.10 0100 01*
计算浮点存储形式各部分的值s=0;
e=127d+6=133d=1000 0101b
m=100 1000 1000 0000 0000 0000
所以c的浮点数是:0 100 0010 1 100 1000 1000 0000 0000 0000
十六进制数表示: 4 2 c 8 8 0 0 0
所以将100.25赋给浮点型变量c,在电脑内部就是将42C88000赋给变量c;
在汇编代码00401014处果然有一条mov dword ptr [ebp-C], 42C88000命令,这就验证了我们做的转化是正确的。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)