c语言浮点数应用(.浮点数的困惑)
c语言浮点数应用(.浮点数的困惑)C语言在使用运算符进行数值运算时,每一个数据都是有各自对应的类型,不同类型的数值进行混合运算时可能会出现意想不到的结果,比如下面的代码计算线段三等分问题:浮点型数值与整型数值一样支持基本数学运算,图1中代码第10行定义了一个半径为5的浮点型变量radius,使用圆形的面积公式:S=π*radius*radius,第11行代码计算出半径为5的圆所对应的面积是多少,并将这个面积值输出至屏幕上。图2使用%f转换符进行浮点型数值输出时,小数点后面的数字位数默认为6位,因此在图2中显示结果为3.140000而不是3.14,可以通过设置转换符精度来控制输出小数部分的位数,比如使用下面的代码可以只显示小数点后面的两位数字。printf("f1 = %.2f\n" f1);
C语言中浮点数与整数是两个不同的类型,浮点数可以简单的认为是它既包含整数部分又包含小数部分,整数部分和小数部分使用小数点进行分割,如3.1415926。浮点数在C语言中有两种基本类型float和double,分别称为单精度浮点数和双精度浮点数,二者所表示的数值范围是不同的。
我们通过下面的代码熟悉下如何使用printf函数输出浮点数值。
图1
图1中第6行代码使用float关键字定义了一个浮点数,其值初始化为3.14,第7行代码通过printf函数将浮点型变量f1的值输出至屏幕上,printf函数的第一个参数使用了转换符%f 这个转换符就是专门处理浮点型数值。
图2
使用%f转换符进行浮点型数值输出时,小数点后面的数字位数默认为6位,因此在图2中显示结果为3.140000而不是3.14,可以通过设置转换符精度来控制输出小数部分的位数,比如使用下面的代码可以只显示小数点后面的两位数字。
printf("f1 = %.2f\n" f1);
浮点型数值与整型数值一样支持基本数学运算,图1中代码第10行定义了一个半径为5的浮点型变量radius,使用圆形的面积公式:S=π*radius*radius,第11行代码计算出半径为5的圆所对应的面积是多少,并将这个面积值输出至屏幕上。
C语言在使用运算符进行数值运算时,每一个数据都是有各自对应的类型,不同类型的数值进行混合运算时可能会出现意想不到的结果,比如下面的代码计算线段三等分问题:
图3
图3第15行代码定义一个整型变量并初始化为100,第16行代码定义另一个变量num,将其值初始化为3,之后通过执行第17行代码,将浮点型变量average的值初始化为length/num,但是其运行结果如图4所示
图4
在图4的输出界面,average变量的值丢失了小数部分内容,应该为33.333333。是什么原因导致此问题呢?我们通过代码的执行顺序来分析导致此问题的原因。在代码第17行,等号右边的表达式会首先执行,由于length和num都是整型数值,那么二者执行除法运算的结果也是一个整数,即100除以3商为33余数为1,只保留整数33部分,丢弃余数1内容,这样等号右边的表达式已经计算完成,之后就是对浮点变量average进行初始化操作,整数33转换为对应的浮点数即为33.000000。那么,问题来了:如何将计算结果精确到小数点后两位?依据上述分析的原因,等号右侧表达式在进行运算时,只需要含有一个浮点型操作数即可,如图5所示
图5
第19行代码,printf函数第一个参数使用了%.2f转换符,将展示的内容以浮点数的格式输出,只保留小数点后两位。length前面添加了一个(float)类型转换操作符,类型转换操作符是将右侧表达式的内容转换为括号内指定的数值类型,它是一元操作符,执行优先级要高于二元除法操作符,在除号左侧表达式执行完类型转换后,其内容实际为一浮点类型的数值,除号右侧的表达式num进行类型提升,也提升为浮点类型数值,两个浮点数相除结果依旧为浮点型数值,得到正确的输出结果,如下图6
图6
这样我们就弄清楚了不同类型之间进行数值运算时常见的一种错误,数值运算时,如果采用了不同的类型,那么一定要确定所采用的类型是否匹配,是否需要进行类型转换。在本文中也演示了浮点型数值的输出控制和精度显示。