【发布时间】:2020-10-24 20:46:08
【问题描述】:
我对浮点数有基本的了解,并且正在阅读 this article 上面写着:
0.1 + 0.2:这等于 0.3,但在浮点数中:
(0.1 + 0.2) == 0.3为假。这是因为 0.1、0.2 和 0.3 不能以 2 为底的浮点数精确表示。
嗯,根据浮点数的性质确实是这样,不过我写了一个简单的程序来测试:
float a = 0.1;
float b = 0.2;
if(a+b == 0.3)
{
printf("true");
} else
{
printf("false");
}
// result is true
但输出实际上是true。这是我的两个问题:
-
我想会发生什么,因为C使用的是round-to-even舍入模式,所以在四舍五入之后,恰好是真的,我的理解正确吗?
-
如果我的理解是正确的,那么在这种情况下一定有一些指定的浮点数不会是真的,因为舍入失败的可能性仍然很小。所以这一定是某种组合
float a = ...; float b = ...; if(a+b == XXX) // where XXX is the "intuitive" sum of a and b { printf("true"); } else { printf("false"); } //result is false now
我的理解正确吗?
【问题讨论】:
-
你用的是什么编译器?我得到
false用于上面使用 gcc 的第一个代码块。 (可能是因为0.3是double文字。) -
printf("%d\n", (int)(sizeof (double) - sizeof (float))); -
只是为了澄清(除了 DevSolar 的评论),舍入模式在这里大多是无关紧要的,而且是红鲱鱼;在这种情况下,任何其他舍入模式都会显示相同的行为,因为
float的精度太小而无法表达0.1f + 0.2f和0.3f之间的差异(甚至在舍入之前!)。无论如何,舍入失败的可能性不是“小”:有 无限多 数字,float算术会给你错误的结果(与有限精度的无限多的情况相同十进制浮点运算会产生错误的结果)。
标签: c floating-point bit-manipulation