鱼C论坛

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

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

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

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

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

x
测试程序:
#include <stdio.h>  
  
int main(void)  
{  
    printf("%f\n", 0);  
    printf("%f\n", (float)123);  
    printf("%f\n", 123.0);  
  
    return 0;  
}  


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

VC6中反汇编查看一下:
7:        printf("%f\n", 123);  
00401028   push        7Bh      // 这时,123当做int型  
0040102A   push        offset string "%f\n" (0042601c)  
0040102F   call        printf (00401090)  
00401034   add         esp,8  
8:        printf("%f\n", (float)123);  
00401037   push        405EC000h  
0040103C   push        0        // 这时,123被转换为float型  
0040103E   push        offset string "%f\n" (0042601c)  
00401043   call        printf (00401090)  
00401048   add         esp,0Ch  
9:        printf("%f\n", 123.0);  
0040104B   push        405EC000h  
00401050   push        0  
00401052   push        offset string "%f\n" (0042601c)  
00401057   call        printf (00401090)  
0040105C   add         esp,0Ch  


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

#include <stdio.h>  
  
int main(void)  
{  
    _asm push 405EC000H;        // 这里模拟一个123.0的输出  
    printf("%f\n", 0);  
    _asm pop eax;           // 这里 只是为了平衡堆栈,不用管  
    printf("%f\n", (float)123);  
    printf("%f\n", 123.0);  
  
    return 0;  
}  

VC6结果:
7:        _asm push 405EC000H;  
00401028   push        405EC000h  
8:        printf("%f\n", 0);  
0040102D   push        0  
0040102F   push        offset string "%f\n" (0042601c)  
00401034   call        printf (00401090)  
00401039   add         esp,8  
9:        _asm pop eax;  
0040103C   pop         eax  
10:       printf("%f\n", (float)123);  
0040103D   push        405EC000h  
00401042   push        0  
00401044   push        offset string "%f\n" (0042601c)  
00401049   call        printf (00401090)  
0040104E   add         esp,0Ch  
11:        printf("%f\n", 123.0);  
0040104B   push        405EC000h  
00401050   push        0  
00401052   push        offset string "%f\n" (0042601c)  
00401057   call        printf (00401090)  
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-11-27 15:56

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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