C语言中的printf用%d输出float类型数据出现或以%f输出int型数据的结果为什么是0

本文详细解析了C语言中float类型使用%d输出总是0的原因,并介绍了如何正确输出浮点数在内存中的存储形式。同时,还探讨了整型数据使用%f输出时的显示结果。
*******************************float类型%d输出**************************************
       floata=7.5f;      如果用printf("%d",a);输出的是0。 
      但float型用%d输出是否一定是0呢,答案肯定不都是0;
       为什么 7.5用%d输出的是0?分析如下:
      首先来了解下printf的输出格式,int 和 long int 都是32位的,用%d输出;float 、double都是%f输出,但float 是32位的,double 是64位的,所以在参数传递的时候C语言统一将 float 类型数值传换为 double类型再传入 printf 函数。如果是32位整型则输出格式为%lld。
       下面来讲一下 float a=7.5f ;printf("%d",a)输出为0的情况:
      %d只输出低32位的数据,并将这些32位二进制以十进制数输出,编译器首先将7.5从float类型转换为double类型,7.5在内存中的存放方式是0x40f00000,转换成double类型在内存中的数据就是这个0x401e000000000000,这个内存数据可以很明显看出低32位全是0,而%d则只能截取到低32位,所以这个以%d输出7.5的数值当然是0了。如大家不相信可以用%lld输出看看,这个%lld就很读到低64位数据,读出的结果就是0x401e000000000000,在屏幕上看到一个很大的十进制数。
      如果我一定要输出7.5在内存中的存放方法怎么办呢?
      可以用printf("%d",*(int*)&a);这里做了一下处理,不是直接把a传进来,把a所在地址里的内容处理了一下,不管a是什么类型,只对地址进行操作,利用(int*)&a,将a所在地址中的内容0x40f00000直接当成 int 类型传给printf,int的类型数据不会再转成double类型了,所以输出正常,这个只是针对浮点型数据只占低32位,如果输出64位还得用%lld格式控制输出。
      如果用printf("%d",(int)a),输出行不行,这个强制类型转换只针对a的数据类型进行转换,7.5转换 int类型是7,而上面的*(int*)&a,是对内存中的实际存储数据进行操作,蔽开数据类型这一层面,只将这个数据0x40f00000直接转成int类型输出。而(int)a,要先看a的类型,C语言会根据所要数据类型,对内存存储的数据进行改变,以便可以用int类型正确解析内存数据。
      如果用printf("%d",(float)a),输出什么,输出的是0,这个只是将a的float类型还转成float类型,还是自动转成doube类型,传给printf函数。
      为什么float非要转成double类型呢,因为printf格式控制浮点型输出只有%f,所以统一按doube类型输出,不像整型有32位的%d或%ld,64位的有%lld,这就将32位整型和64位整型用不同的格式控制分开了,而%f则没有,所以printf输出的浮点数其实是统一遍历了64位内存,如果float传入printf没有进行转换,那么printf输出高32位数据将不可预知,printf输出结果也就不正确了,因此传入printf的浮点数都会被编译器隐含转成double类型。
***********************int类型%f格式输出************************************
       如果定义了inta=0x40f00000;用printf("%f",a)输出的结果是多少呢?
      答案是0,至少我们看的屏幕上显示的是0.000000,实际值可不是0啊,只是我们显示的精度只能有15位小数,而实际的数据可能很小很小,0.0000....000几百个0后会有几个有效数据,我们分析一下。
      首先C语言把a传进printf,因为a是整型,所以不会自动转成double型数据,直接将0x40f00000传进printf,而%f寻的是64位内存,也就是把0x0000000040f00000这个内存中的数据当成浮点型输出来,那浮点型的数据是多少呢,又是怎么存储的呢?
64位浮点数的存放方式:
       63位              62~52位              51~0位
       1个符号位      11个阶数              52个尾数
      从0x0000000040f00000来看
      1)符号位是0,表示正
       2)阶数是0,表示-1023 + 1023 =0,用指数表示:1.#*2^-1023,‘#’是代表尾数。
      3)尾数就是,0x0000040f00000
      4)浮点二进制表示
 2#1.0000000000000000000001000000111100000000000000000000*2^(-1023),-1023次方可想而知有多小。
这就是为什么我们的int型数据用%f输出是0.000000的原因。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值