如何乘以ANSI C中的浮点数?
下面的代码:如何乘以ANSI C中的浮点数?
float numberForFactorial;
float floatingPart = 1.400000;
int integralPart = 1;
numberForFactorial = ((floatingPart) - (float)integralPart) * 10;
printf("%d", (int)numberForFactorial);
返回3而不是4.你能解释我为什么?
最靠近1.400000
的float
略小于1.4
。您可以验证通过做
printf("%0.8hf\n", floatingPart);
从ideone结果是1.39999998
。这意味着小数点后第一位数字的10倍是3
。
要避免此问题,请使用舍入而不是截断。一个简单的方法,以圆是截断前加入一半:
printf("%d", (int)(numberForFactorial + 0.5f));
将打印4
如您所期望。您也可以使用round
,rint
,lround
或modf
获得相同的结果:https://www.gnu.org/software/libc/manual/html_node/Rounding-Functions.html。舍入是一个复杂的主题,所以选择最适合您的情况约束的方法。
这是由于浮点值的二进制表示。更具体地,0.4
或2/5
不能与尾数表示为任何组合等之和1/2 + 1/4 1/8 + + ...
字面1.400000
被存储为在其二进制更接近于1.399999976158142
表示。转换到int
截断非整数部分,给出三个作为最终结果。要想迂回,C标准不要求浮点数据类型的基于二进制的表示,但IEEE 754事实上是当今计算中的标准。
希望你不介意我的编辑。 +1 –
嗯...是的,当我学习“计算机系统程序员的视角”第三版,第2章,第110页时,我知道1/2 + 1/4 + 1/8的事情 – Nikitas
可能因为'1.40000'被内部存储为'1.399999'或类似的东西。如预期的那样,(int)3.99999'为'3'。 –
当你做'printf(“%0.6f \ n”,floatingPart)时,你会得到什么;'? –
要扩展@ MadPhysicist的评论,从浮点到整数的转换将截断为零。 –