如何在 ANSI C 中乘以浮点数?
How to multiply floating point in ANSI C?
以下代码:
float numberForFactorial;
float floatingPart = 1.400000;
int integralPart = 1;
numberForFactorial = ((floatingPart) - (float)integralPart) * 10;
printf("%d", (int)numberForFactorial);
Returns 3 而不是 4。你能解释一下为什么吗?
这是由于浮点值的二进制表示。更具体地说,0.4
或 2/5
不能用尾数表示为任何组合的总和,例如 1/2 + 1/4 + 1/8 + ...
文字 1.400000
在其二进制表示中存储为更接近 1.399999976158142
的内容。转换为 int
会截断非整数部分,最终结果为 3。
迂腐地说,C 标准不需要浮点数据类型的基于二进制的表示,但是 IEEE 754 实际上是当今计算中的标准。
最接近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。舍入是一个复杂的话题,因此请选择其约束条件最适合您情况的方法。
以下代码:
float numberForFactorial;
float floatingPart = 1.400000;
int integralPart = 1;
numberForFactorial = ((floatingPart) - (float)integralPart) * 10;
printf("%d", (int)numberForFactorial);
Returns 3 而不是 4。你能解释一下为什么吗?
这是由于浮点值的二进制表示。更具体地说,0.4
或 2/5
不能用尾数表示为任何组合的总和,例如 1/2 + 1/4 + 1/8 + ...
文字 1.400000
在其二进制表示中存储为更接近 1.399999976158142
的内容。转换为 int
会截断非整数部分,最终结果为 3。
迂腐地说,C 标准不需要浮点数据类型的基于二进制的表示,但是 IEEE 754 实际上是当今计算中的标准。
最接近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。舍入是一个复杂的话题,因此请选择其约束条件最适合您情况的方法。