鱼C论坛

 找回密码
 立即注册
查看: 1779|回复: 2

[技术交流] 【菜狗正在爬行】printf格式输出float类型结果不正确

[复制链接]
发表于 2016-11-10 15:22:51 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
测试程序:

  1. #include <stdio.h>  
  2.   
  3. int main(void)  
  4. {  
  5.     printf("%f\n", 0);  
  6.     printf("%f\n", (float)123);  
  7.     printf("%f\n", 123.0);  
  8.   
  9.     return 0;  
  10. }  
复制代码



===========   大家先猜测一下输出结果,然后看下边  --------------------------

VC6中反汇编查看一下:
  1. 7:        printf("%f\n", 123);  
  2. 00401028   push        7Bh      // 这时,123当做int型  
  3. 0040102A   push        offset string "%f\n" (0042601c)  
  4. 0040102F   call        printf (00401090)  
  5. 00401034   add         esp,8  
  6. 8:        printf("%f\n", (float)123);  
  7. 00401037   push        405EC000h  
  8. 0040103C   push        0        // 这时,123被转换为float型  
  9. 0040103E   push        offset string "%f\n" (0042601c)  
  10. 00401043   call        printf (00401090)  
  11. 00401048   add         esp,0Ch  
  12. 9:        printf("%f\n", 123.0);  
  13. 0040104B   push        405EC000h  
  14. 00401050   push        0  
  15. 00401052   push        offset string "%f\n" (0042601c)  
  16. 00401057   call        printf (00401090)  
  17. 0040105C   add         esp,0Ch  
复制代码



根据堆栈,稍稍修改一下,测试:


  1. #include <stdio.h>  
  2.   
  3. int main(void)  
  4. {  
  5.     _asm push 405EC000H;        // 这里模拟一个123.0的输出  
  6.     printf("%f\n", 0);  
  7.     _asm pop eax;           // 这里 只是为了平衡堆栈,不用管  
  8.     printf("%f\n", (float)123);  
  9.     printf("%f\n", 123.0);  
  10.   
  11.     return 0;  
  12. }  
复制代码


VC6结果:

  1. 7:        _asm push 405EC000H;  
  2. 00401028   push        405EC000h  
  3. 8:        printf("%f\n", 0);  
  4. 0040102D   push        0  
  5. 0040102F   push        offset string "%f\n" (0042601c)  
  6. 00401034   call        printf (00401090)  
  7. 00401039   add         esp,8  
  8. 9:        _asm pop eax;  
  9. 0040103C   pop         eax  
  10. 10:       printf("%f\n", (float)123);  
  11. 0040103D   push        405EC000h  
  12. 00401042   push        0  
  13. 00401044   push        offset string "%f\n" (0042601c)  
  14. 00401049   call        printf (00401090)  
  15. 0040104E   add         esp,0Ch  
  16. 11:        printf("%f\n", 123.0);  
  17. 0040104B   push        405EC000h  
  18. 00401050   push        0  
  19. 00401052   push        offset string "%f\n" (0042601c)  
  20. 00401057   call        printf (00401090)  
  21. 0040105C   add         esp,0Ch  
复制代码



小结:printf函数的格式输出符没有类型转换的功能,只能显式的类型转换。
例如printf("%f", (double)123);
如果你认为它可以自动类型转换,就会出现意想不到的结果。
例如printf("%f", 123);这个时候,%f会要求系统从栈中取8个字节数据进行解析,可惜啊···我们的123不够,所以取出来的数···如果VC-Debug模式下貌似是edi的值,其他的···大家自己研究一下,还有那个%f对应的数据表示的如何解析的?大家可以网上查一下浮点类型在内存中存储形式。


评分

参与人数 2荣誉 +8 鱼币 +16 贡献 +3 收起 理由
不二如是 + 5 + 11 + 3 好好学习,天天想上
~风介~ + 3 + 5 支持楼主!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-11-10 15:25:59 | 显示全部楼层
又一个版主被老司机@不二如是 给带坏了~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-11-10 15:28:16 | 显示全部楼层
~风介~ 发表于 2016-11-10 15:25
又一个版主被老司机@不二如是 给带坏了~

多么严肃的斑竹~

多么纯洁的一个帖子~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-19 07:53

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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