C语⾔:float类型%d输出
float类型%d输出
float a=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类型正确解析内存数据。
浮点型变量float如果⽤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格式输出************************************
如果定义了int a=0x40f00000;⽤printf("%f",a)输出的结果是多少呢?
答案是0,⾄少我们看的屏幕上显⽰的是0.000000,实际值可不是0啊,只是我们显⽰的精度只能有15位⼩数,⽽实际的数据可能很⼩很⼩,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的原因。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论