printf("%f\n", 3);

原创 2012年03月29日 10:32:49

 原因在于printfprintf不会关心你输入的参数的类型,你输入的实际是 
printf("%f",3)
,但是这个整型3不会被隐式类型转换为浮点型,而是被直接按内存内容当作浮点型 

也就是说,内部使用等价于 
int i = 3; 

printf("%f", *(float*)&i) 

不幸的是,整型3在内存布局上如果看成浮点数,它就是接近于

完整的说明一下吧。 
首先printf("%f",10/3);等价于 printf("%f",3);也就是说在这种情况下C不支持类型转换。并且"%f"处理的是double类型的浮点数也就是64位,而且默认的显示精度是小数点后6位。 
然后要考虑浮点数的表示方法,根据IEEE 754标准对64位浮点数采用的表示为: 
数符(1位)|阶码11位) | 尾数52位) 
好了,可以解决问题了。你的360 +11知道为什么了吧?数太小了!在仅仅可以显示小数点6…

接近正确,整数3其实对应的是601124032位随机值
内存中整数3就是0000001100000000 00000000 00000000
后面紧跟的是4字节堆栈上的当前值(可能是CS:IP) 

 

这是不定参数的特点,没有类型检查,没有类型转换

不过如果打印一个固定值都能出现随机值,只能说crt出问题了 
可能的原因(首先你要看一遍11楼给的说明) 
因为进入printf时,堆栈上传进来的只有sizeof(int)个字节,而double需要的字节数比int多,因此va_arg转换时除了你传进去的4字节之外,还用了堆栈上的相连四个字节,而这四字节内容不是你设置的,可能会随编译器、OS不同由随机产生的可能性

 

记得之前看过一个介绍,printf输出时,float是当double处理的

下面的代码似乎能验证这一点:

//看起来不匹配,但都打印出了最后一个数字5,floatdouble处理了
printf("%f,%d\n",3,4,5); 
printf("%d,%d,%d\n", (float)3.45);

 

汇编代码

; 4    :     printf("%f\n",1);

  00018    6a 01          push1
  0001a    6800000000push     OFFSET FLAT:??_C@_03FBAH@?$CFf?6?$AA@ ; `string'
  0001f    e8 00000000call     _printf
  0002483 c4 08         add     esp, 8

; 5    :     printf("%f\n",1.0);

  00027   680000 f0 3f push1072693248; 3ff00000H
  0002c    6a 00          push0
  0002e    6800000000push     OFFSET FLAT:??_C@_03FBAH@?$CFf?6?$AA@ ; `string'
  00033    e8 00000000call     _printf
  00038    83 c4 0c       add     esp, 12; 0000000cH
 


上面的是printf("%f\n",1);printf("%f\n",1.0);的反汇编代码,说明若是浮点型数,编译器会把它转化成浮点格式在入栈的,而整形是不会的转化直接压入的,而printf函数根据地2个参数%f认为前面压入的是浮点型来处理了 

 

 http://topic.csdn.net/u/20090305/22/6365501d-844e-4fd4-9905-ac1c703ba05a.html

printf("%f",10/3);的结果是什么?

转载自:http://www.cnblogs.com/xkfz007/archive/2012/05/18/2508265.html printf("%f",10/3);的结果是什么? ...
  • u011493488
  • u011493488
  • 2014年11月06日 15:55
  • 888

printf 使用%f输出整形变量,为什么为0?

#include void main(){      int i = 65535;     printf("%f",i) } 1,之所以没输出65535,这是C语言设计的原因。 2,之所以输出0,这...
  • Mark_tanlixing
  • Mark_tanlixing
  • 2014年12月17日 08:54
  • 1669

为什么printf不能用%lf输出double型,而用%f?

来源: 为什么使用%lf读取double型的值,而用%f进行显示?  今天看到一篇好文章,mark一下。 出去旅游了一下,所以有些天没敲代码,于是又弱爆了~忘掉了题目中的东西,结果出现了问题...
  • nickwong_
  • nickwong_
  • 2014年08月16日 18:51
  • 4152

c++ printf参数练习

#include using namespace std; /** %d 十进制有符号整数 %u 十进制无符号整数 %f 浮点数 %s 字符串 %c 单个字符 %p 指针的值 %e 指数形式的浮点数...
  • earbao
  • earbao
  • 2014年05月13日 11:40
  • 1248

为什么printf()用%f输出double型,而scanf却用%lf呢

原文:http://blog.sina.com.cn/s/blog_899f46e501014cu6.html  示例:double x;scanf(“%f”,&x);输入“123.4”,输出...
  • wlx65003
  • wlx65003
  • 2015年12月24日 21:21
  • 3063

printf 格式化控制

printf()函数是格式输出函数,请求printf()打印变量的指令取决与变量的类型.例如,在打印整数是使用%d符号,在打印字符是用%c 符号.这些符号被称为转换说明.因为它们指定了如何不数据转换成...
  • tyy_ing
  • tyy_ing
  • 2013年11月21日 13:32
  • 2866

单片机printf使用

一、printf常用说明 printf的格式控制的完整格式: %  -  0  m.n  l或h  格式字符 下面对组成格式说明的各项加以说明: ①%:表示格式说明的起始符号,不可缺少。 ②...
  • graduation201209
  • graduation201209
  • 2015年11月02日 20:49
  • 1537

fork()代码中为什么if(){} else{}都能执行?

问题原文: 解答摘要: 解答原文: fork的一个例子,好像人家是讲得很详细了,我还是不明白 要搞清楚fork的执行过程,就必须先讲清楚操作系统中的“进程(process)”概...
  • feliciafay
  • feliciafay
  • 2014年11月18日 07:03
  • 1659

Ucos printf 浮点数 乱码 问题

1. 问题描述: 当使用uocs printf(),sprintf()打印浮点数问题会出问题,但是裸机不会出问题 我现在使用STM32跑UCOS,在使用sprintf打印float类型时候...
  • jinhongdu
  • jinhongdu
  • 2013年03月04日 19:45
  • 3175

NYOJ 题目35 表达式求值 (栈的应用)前中后缀,

表达式求值 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 ACM队的mdd想做一个计算器,但是,他要做的不仅仅是一计算一个A+B的计算器,他想实现随便输入一个表...
  • u011282069
  • u011282069
  • 2013年07月30日 15:22
  • 1636
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:printf("%f\n", 3);
举报原因:
原因补充:

(最多只允许输入30个字)