第18题  浮点数四舍五入问题

试编写函数fun,通过形参h接收一个实数,先将其转换为绝对值,再对该绝对值进行四舍五入保留2位小数,即对小数点后第3位进行四舍五入处理,并将舍入结果返回调用者。

例如:若h接收2345.676,则fun返回2345.68,按%f格式输出显示为2345.680000;若h接收1234.564,则fun返回1234.56,按%f格式输出显示为1234.560000。

注意:部分源程序在PROG1.C中,请勿改动已给定的任何内容,只在函数fun的指定位置填入你编写的若干语句。

PROG1.C:

PROG18-01

参考答案:

PROG18-02

运行结果:

PROG18-03

程序解析:

形如1234的整型常量是int型。long常量要写后缀字母l或L,如123456789L;整型常量数值太大以至于int变量无法容纳的也被视为long型。无符号常量要写后缀字母u或U,后缀组合ul或UL表示unsigned long型。因此本题中出现的100为int常量。

浮点常量包含小数点(如123.4)或科学记数指数符号(如1e−2)或二者均有,其类型是double(除非加了后缀)。后缀f或F表示float常量;l或L表示long double。因此本题中出现的0.5、100.0为double常量。

main函数调用scanf读取字符串−2345.676,按确定规则、将其转换为机内double型的浮点值为−2345.6759999999999,由于实际实数的连续无穷性与机内浮点数的离散有穷性之间的矛盾,这两者通常并不完全相同但足够接近,对实际问题的求解一般没有影响。因此用户在键盘键入的字符串−2345.676,被scanf读取转换为−2345.6759999999999并存储于double变量h中 ,按%f格式显示为−2345.676000,这种格式只显示小数点后6位(四舍五入保留6位小数)。转换为绝对值并存储于h后变成2345.6759999999999,按%f格式显示为2345.676000。

本题要求在不使用库函数的前提下,完成浮点数的四舍五入,旨在考查类型转换。下面解释表达式(int)(h∗100 + 0.5) / 100.0,h本是double型,其值为2345.6759999999999,先将int型常量100转换为double型再与h进行浮点乘法,结果仍是double型,其值为234567.59999999999,这是向高、向宽类型看齐的转换规则(int要转换为double)。再与double型常量0.5相加,得到double值234568.09999999999,再对该值进行int强制类型转换后得到int型值234568,doubleint的强制转换就是把小数部分截弃。再将int型值234568转换为double型与double型常量100.0进行浮点除法,得到double型浮点值2345.68,按%f格式显示为2345.680000。简而言之,就是乘100将小数点后移2位、加0.5实现舍入、再除100把小数点挪回来。

知识点:

① 整型常量的格式。

② 浮点常量的格式。

③ scanf总是从字符文本流读取符合格式要求的字符串,再按格式符的要求,将读取到的字符串转换为各种格式的机内值,并转储于相应变量之中。

④ 在C语言中,对于二元操作符,规定了一套自动类型转换规则,基本思想是向高、向宽类型看齐,即若两个操作数类型不一致,先把低、窄类型转换为高、宽类型,再进行运算,结果也是高、宽类型。所谓高、宽就是占用存储字节数较多、表示范围更大的意思。

⑤ 强制类型转换的含义及规则。强制类型转换是一元操作符,比加减乘除二元操作符的优先级高,所以在表达式(int)(h∗100 + 0.5) / 100.0的求值过程中,先对(h∗100 + 0.5)进行int强制转换,再与100.0相除。

⑥ 在程序文本中出现的整型常量、浮点常量在本质上等同于scanf所读取的字符串,要由编译器将其转换为各种格式的机内值。

⑦ 对于浮点数的输入, scanf所读取字符串的字面数值与其转换后的机内数值一般并不相同但足够接近,对实际问题的求解一般没有影响。根源在于实际实数的连续无穷性与机内浮点数的离散有穷性之间的矛盾。

返回