如何乘以ANSI C中的浮点数?

问题描述:

下面的代码:如何乘以ANSI C中的浮点数?

float numberForFactorial; 
    float floatingPart = 1.400000; 
    int integralPart = 1; 

    numberForFactorial = ((floatingPart) - (float)integralPart) * 10; 

    printf("%d", (int)numberForFactorial); 

返回3而不是4.你能解释我为什么?

+0

可能因为'1.40000'被内部存储为'1.399999'或类似的东西。如预期的那样,(int)3.99999'为'3'。 –

+0

当你做'printf(“%0.6f \ n”,floatingPart)时,你会得到什么;'? –

+0

要扩展@ MadPhysicist的评论,从浮点到整数的转换将截断为零。 –

最靠近1.400000float略小于1.4。您可以验证通过做

printf("%0.8hf\n", floatingPart); 

ideone结果是1.39999998。这意味着小数点后第一位数字的10倍是3

要避免此问题,请使用舍入而不是截断。一个简单的方法,以圆是截断前加入一半:

printf("%d", (int)(numberForFactorial + 0.5f)); 

将打印4如您所期望。您也可以使用roundrint,lroundmodf获得相同的结果:https://www.gnu.org/software/libc/manual/html_node/Rounding-Functions.html。舍入是一个复杂的主题,所以选择最适合您的情况约束的方法。

+0

oh f ** k ..现在我明白了为什么...... – Nikitas

+0

@Nikitas。如果解释了需要解释的内容,请随意选择此答案。 –

+0

是啊,花车是a **中的痛苦。 –

这是由于浮点值的二进制表示。更具体地,0.42/5不能与尾数表示为任何组合等之和1/2 + 1/4 1/8 + + ...

字面1.400000被存储为在其二进制更接近于1.399999976158142表示。转换到int截断非整数部分,给出三个作为最终结果。要想迂回,C标准不要求浮点数据类型的基于二进制的表示,但IEEE 754事实上是当今计算中的标准。

+1

希望你不介意我的编辑。 +1 –

+0

嗯...是的,当我学习“计算机系统程序员的视角”第三版,第2章,第110页时,我知道1/2 + 1/4 + 1/8的事情 – Nikitas