找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 482|回复: 4

printf打印float错误引起的思考

[复制链接]

205

主题

172

回帖

6921

积分

论坛元老

积分
6921
发表于 2013-8-8 09:47:06 | 显示全部楼层 |阅读模式
昨天跟一个朋友讨论一个问题:float n1=3.0;
double n2=3.0;
long n3=2000000000;
long n4=1234567890;
printf("%ld %ld %ld %ld\n", n1, n2, n3, n4);


在x86 32位机上执行,输出结果是:0 1074266112 0 1074266112
按照我的理解,float和long在32位机下都占4个字节,即使无法格式化为long进行输出,后面的值也不至于都出问题。


实际里面涉及以下的知识,
1. 把上面的代码反汇编可以看到:
mov 0x80494b4,%eax
mov %eax,0x18(%esp)
mov 0x80494b0,%eax
mov %eax,0x14(%esp)
fldl 0x80494a8
fstpl 0xc(%esp)
flds 0x80494a0
fstpl 0x4(%esp)
movl $0x8048478,(%esp)
call 0x804828c <printf>
我先后把这几个变量定义成了局部和全局的进行了测试,这段是用全局的汇编码。
关键是这几句:
fldl 0x80494a8
fstpl 0xc(%esp)
flds 0x80494a0
fstpl 0x4(%esp)
fldl把浮点地址交给浮点运算寄存器,浮点寄存器是64为精度的,然后fstpl再把值取出按照64位入栈,表象就是按照double类型入栈了


。所以虽然内存中单精度浮点数是以4字节存储的,但编译器把它转成了8字节进行处理。
所以最后在栈里的存储就成了
| 00 00 00 00 |<--ESP
| 40 40 00 00 |
| 00 00 00 00 |
| 40 40 00 00 |
| 49 96 02 d2 |
| 77 35 94 00 |<--EBP


2. printf的处理方式是将输入参数按照字符串进行格式化解析,由于输入的是ld ld ld ld,按照4字节依次进行取值,就得到了上面的结果。


3. float是单精度浮点,遵从IEEE754, S(1)-E(8)-M(23)。3二进制位11,表示为:1.1×2^1 => 指数部分127+1=128-


>10000000,小数部分为1,因此其浮点表示为:
0 10000000 10000000000000000000000,也就是上面1中看到的0x40400000,打印出的十进制就是1074266112。


后来又找来台cavium64位的机器上跑了一下,发现都是正确的,即使按照%d方式输出也没有问题,没法在cavium上反汇编无法确认。

1793

主题

457

回帖

0

积分

管理员

积分
0
发表于 2013-8-8 19:49:00 | 显示全部楼层
顶你个肺

0

主题

1

回帖

0

积分

新手上路

积分
0
发表于 2013-8-9 10:30:21 | 显示全部楼层
float在printf里面会被转换成为double型,,所以3.0在内存里是以double型存在的,存在形式是0x40080000,指数位是11位,最后结果才是1074266112,而0x40400000=1077936128,lz再用计算器验证一下

205

主题

172

回帖

6921

积分

论坛元老

积分
6921
 楼主| 发表于 2013-8-9 11:09:16 | 显示全部楼层

回 gexueyuan 的帖子

gexueyuan:float在printf里面会被转换成为double型,,所以3.0在内存里是以double型存在的,存在形式是0x40080000,指数位是11位,最后结果才是1074266112,而0x40400000=1077936128,lz再用计算器验证一下&#160;(2013-08-09 10:30)&#160;
哈哈,感谢指正,计算器计算才是王道。但对于理解应该不存在大问题

0

主题

13

回帖

0

积分

新手上路

积分
0
发表于 2013-10-15 11:17:59 | 显示全部楼层
顶顶顶顶顶顶顶
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

果子博客
扫码关注微信公众号

Archiver|手机版|小黑屋|风叶林

GMT+8, 2026-2-1 04:41 , Processed in 0.147592 second(s), 20 queries .

Powered by 风叶林

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表