float强制转换的问题及解释

 

#include <stdio.h>
int main() {
        float b = 0.58;
	int a;
	a = (int)(b * 100);
	printf("%f , %d\n", b*100, a);
	getchar();
	return 0;
}

 

输出结果为


 

a 在强制转换的时候,直接保留整数部分时,得到57,少了1

 

将b的值改为0.01时,

输出结果如下,


 很奇怪,输出为1.000000, 而强制转换保留整数部分时竟然得到的是0

 

放大%f 的输出格式 改为%.10f ,输出10位,结果如下


虽然float类型能够表示的位数是6到7位, 但是足以说明浮点数在计算机中的表示是不准确的

尤其在float 转 int时, 更加应该注意, 如果想四舍五入,在浮点数加上0.5以后,再进行强制转换

 

以下参考http://www.cnblogs.com/tekson/archive/2009/07/16/1524604.html
float强制转换的问题及解释_第1张图片
 

以下参考http://www.cnblogs.com/Xiao_bird/archive/2010/03/26/1696908.html

printf格式串中的%f到底是float还是double?实验来证明!

最近在CSDN上看到一个网友写下了类似如下代码,想以小数格式输出一个整数:

int  a  =   0 , b  =   0 ;
printf(
" %f, %d " , a, b);

可是运行结果并不尽如人意,%f字段输出了0,%d字段输出一个较大的数据。

因为我最近刚阅读了浮点数的内存表示方法,所以对上述代码做出解释如下:
%f为double类型,需要两个字节表示,所以,printf在遇到%f时即将a,b的两个整型数据都读了去,而到了需要输出%d的时候,只能读取b的下一个单元,自然不是所期望的数据了。

但是有朋友说%f是float类型,%lf才是double类型,具此我特意查阅了MSDN和Linux man手册,均没有发现此类描述,在linux man手册中,说明%lf为long double类型。
为了说明问题,我又做了几个实验:

实验一,检查%f需要读取几个字节

int  a = 0 , b = 0 , c = 5 ;
printf(
" %f,%d\n " , a, b, c);

输出结果:
0,5
结论:%f读取8个字节,即两个整型大小

实验二,检查%lf需要读取几个字节

int  a = 0 , b = 0 , c = 5 ;
printf(
" %lf,%d\n " , a, b, c);

输出结果:
0,5
结论:%lf也读取8个字节(也许和机器位宽有关,我是32位的机器)

实验三,检查printf读取float类型数据

float  a = 0.0f ;
int  b = 5 ;
printf(
" %f,%d\n " , a, b);

输出结果:
0.0,5
结论:float类型只占4个字节的数据,但前面实验一已经证明%f会读8个字节,即double类型的宽度,所以,编译器在将float类型参数入栈的时候,事先转换成了double类型。

实验四,再次证明实验三的结论

float  a = 0.0f ;
int  b = 5 ;
printf(
" %d,%d,%d\n " , a, b);

输出结果:
0,0,5
结论:a在入栈的时候,占了8个字节。

以上4步,我觉得可以证明%f是按double类型输出的了,另外,我也知道了float类型在作为参数进行传递的时候,编译器会先将它转换成double类型。

 

 

你可能感兴趣的:(float)