提问人:Minimihi 提问时间:7/4/2013 最后编辑:phuclvMinimihi 更新时间:8/14/2018 访问量:74
浮点数行为
Float number behavior
问:
我的室友刚刚提出了一个问题。
为什么在 php(也许还有其他语言)并且是 7?floor($foo)
(int)$foo
$foo = (0.7 + 0.1) * 10;
var_dump(
$foo,
floor($foo),
(int)$foo,
ceil($foo),
is_infinite($foo),
is_finite($foo));
结果
float(8)
float(7)
int(7)
float(8)
bool(false)
bool(true)
请注意,这不是一个无限大的数字。$foo
从回答中我可以看出,每个人都说它实际上是x.(9)
但是,数字是x.(9)
而不是现实生活中应有的实际x背后的原因是什么?
答:
并非总是如此。如果由于浮点不精确而最终得到 8.0000001,则下限将捕捉到 8。有时可能是 7.999999,它会捕捉到 7。
很有可能,如果你将 0.x 乘以 y(在大多数语言中被读作 int),它会完整地出现,所以你不会看到这种行为。
这在其他语言中也类似。
因为 0.7 和/或 0.1 在内部实际上是 0.6999999......或 0.09.....
这意味着你的 (0.7 * 0.1) 更像是 0.7999.....乘以 10 和 int/floor 后,最终得到 7。
floor 函数向下舍入到最接近的整数。转换为 int 只是丢弃了小数部分。 是一个浮点数,它不完全是 8,(必须是 7.99999...),因此您可以观察到该行为。$foo
如果分母包含的质因数不在基数的质因数列表中(即 2 和 5)中,则有理数将变为重复小数
- 如果约化分数的分母包含不是基数的质因数,则有理数具有有限长度小于完全约化分数分母值的无限重复序列。重复序列在基数点之后有一个有限长度的瞬态,如果约化分数也与基数共享一个质因数。
计算机中的浮点类型几乎总是二进制的,因此任何在有理表示中分母不是 2 的幂的数字都是无限周期小数。例如,在 IEEE-754 单精度中,0.1 将四舍五入为 0.100000001490116119384765625,这是最接近的 2s 的幂和
这里 0.7 和 0.1 都不能用二进制浮点表示,0.8 也不是。它们的总和也不等于 0.8:尝试打印,你会得到结果为 false。它实际上略低于 0.8。但它不是像你那样的重复小数,而是一个在小数部分具有有限数量的 9 的值。0.7 + 0.1 == 0.8
7.(9)
结果 和 结果为 7。如果你取 or 结果,你会得到 8ceil
int
floor
round
评论
$foo
在十进制中不是无限的,但在二进制中是无限的。