下面的代码:
float numberForFactorial; float floatingPart = 1.400000; int integralPart = 1; numberForFactorial = ((floatingPart) - (float)integralPart) * 10; printf("%d", (int)numberForFactorial);
返回3而不是4。你能解释一下为什么吗?
qni6mghb1#
最接近1.400000的float略小于1.4。
1.400000
float
1.4
printf("%0.8hf\n", floatingPart);
ideone的结果是1.39999998。这意味着小数点后第一位的10倍是3。为了避免这个问题,请使用舍入而不是截断。一个简单的舍入方法是在截断之前添加一半:
1.39999998
3
printf("%d", (int)(numberForFactorial + 0.5f));
将按预期打印4。您也可以使用round、rint、lround或modf来获得相同的结果:https://www.gnu.org/software/libc/manual/html_node/Rounding-Functions.html。舍入是一个复杂的主题,因此请选择其约束条件最适合您的情况的方法。
4
round
rint
lround
modf
vuv7lop32#
这是由于浮点值的二进制表示。更具体地说,0.4或2/5不能用尾数表示为1/2 + 1/4 + 1/8 +...文字1.400000在其二进制表示中被存储为更接近1.399999976158142的内容。转换为int会截断非整数部分,最终结果为3。虽然C标准不要求浮点数据类型的二进制表示,但IEEE 754实际上是当今计算中的标准。
0.4
2/5
1.399999976158142
int
2条答案
按热度按时间qni6mghb1#
最接近
1.400000
的float
略小于1.4
。ideone的结果是
1.39999998
。这意味着小数点后第一位的10倍是3
。为了避免这个问题,请使用舍入而不是截断。一个简单的舍入方法是在截断之前添加一半:
将按预期打印
4
。您也可以使用round
、rint
、lround
或modf
来获得相同的结果:https://www.gnu.org/software/libc/manual/html_node/Rounding-Functions.html。舍入是一个复杂的主题,因此请选择其约束条件最适合您的情况的方法。vuv7lop32#
这是由于浮点值的二进制表示。更具体地说,
0.4
或2/5
不能用尾数表示为1/2 + 1/4 + 1/8 +...文字
1.400000
在其二进制表示中被存储为更接近1.399999976158142
的内容。转换为int
会截断非整数部分,最终结果为3。虽然C标准不要求浮点数据类型的二进制表示,但IEEE 754实际上是当今计算中的标准。