求解:机内浮点数处理的真实过程!~~

[复制链接]
查看11 | 回复5 | 2021-1-27 06:14:07 | 显示全部楼层 |阅读模式
先看一例:
floata;
a=56.982;
1.浮点常量转换成机内二进制过程如下:
a.分别对整数和小数部分在运算器中转换成二进制形式
56.982=整数部分[0000...000000111000].小数部分[11111011011001000101...]
(存储整数部分和小部分的中间结果的寄存器不知是多少位,这里只算出整数部分中有用的后8位及小数部分中有用的前20位)
b.移位至成32位浮点数的标准格式(尾数占23位,首位1隐藏)
56.982=1.11000111110110110010001
(这里右移了5位)
c.计算出8位的阶码:5+127=10000100
d.符号位(占1位)为0
故56.982机内二进制存储格式为:01000010011000111110110110010001
用下面程序可进行验证.
voidmain()
{
floata=56.982;
unsignedlong*i=&a;
printf("%lx\n",*i);
}
运行结果:4263ed91
printf("%f",a);
2.输出按浮点数754标准存储格式存储0x4263ed91的浮点数
a.符号位0,正
b.计算指数=10000100-01111111=5
c.计算尾数=1.11000111110110110010001
ok问题出现了,
问题一:这里的二进制形式的尾数是通过乘法器?或是除法器?亦或加法器?转换成十进制形式的小数部分的?
计算原理是什么?
问题二:这里尾数的处理要放到寄存器里进行运算的吧,那么它的位数要和寄存器对齐,
那它后面空出的位是补1呢还是补0呢?个人觉得补1,这样可以进步缩小误差.
问题三:小数点后第一位权为0.5,后第二位权为0.25,后第三位权为0.125,...
如此,printf("%f",a);的结果应是:xx.xxx5以5结尾的啊?
而由程序:
voidmain()
{
floata=56.982;
printf("%f",a);
}
的结果是:a=56.981998
我表示不理解,为什么结果不是以5结尾的.求解释
(第三个问题就是第一个问题.要知道问题一的原理,相信问题三就解决了)

这里求对cpu有研究的高人解开我的疑问。

分 -->
回复

使用道具 举报

千问 | 2021-1-27 06:14:07 | 显示全部楼层
问题一:这里的二进制形式的尾数是通过乘法器?或是除法器?亦或加法器?转换成十进制形式的小数部分的?
计算原理是什么?
回答一:不是通过加法器减法器乘法器除法器转换的,而是通过一段子程序转换为字符串,这段子程序由库函数printf调用。要明确的一点是,在计算机内部,所有CPU能理解的“数”永远以二进制形式表现,当需要将这个数以十进制形态显示给人看的时候,通过一段子程序将其转换为字符串形态。
问题二:这里尾数的处理要放到寄存器里进行运算的吧,那么它的位数要和寄存器对齐,
那它后面空出的位是补1呢还是补0呢?个人觉得补1,这样可以进步缩小误差.
回答二:没看明白
问题三:小数点后第一位权为0.5,后第二位权为0.25,后第三位权为0.125,...
如此,printf("%f",a);的结果应是:xx.xxx5以5结尾的啊?
回答三:你前文已经将这个浮点数转换为了二进制,现在你再将你手工转换获得的二进制数转换回十进制,你会发现尾数其实是“5”,只是printf默默的把这个数个四舍五入了。
回复

使用道具 举报

千问 | 2021-1-27 06:14:07 | 显示全部楼层
对CPU没做过多大研究帮顶

回复

使用道具 举报

千问 | 2021-1-27 06:14:07 | 显示全部楼层
硬件还是软件浮点数
回复

使用道具 举报

千问 | 2021-1-27 06:14:07 | 显示全部楼层
定点数与浮点数
回复

使用道具 举报

千问 | 2021-1-27 06:14:07 | 显示全部楼层
在不含有浮点协处理器的CPU上进行浮点与定点数的转换,或者不同进制数之间的转换,都是靠一个循环子程序来实现的,其中的运算步骤只有两种,移位和加法。
你可以找个汇编语言写的浮点数运算例子看看就明白了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行