1

我的室友刚刚提出了一个问题。

为什么在 php(也许还有其他语言)floor($foo)(int)$foo是 7?

$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 ?

4

4 回答 4

1

不总是。如果由于浮点不精确而最终得到 8.0000001,则地板将捕捉到 8。有时可能是 7.999999,它会捕捉到 7。

很有可能,如果您将 0.x 乘以 y(在大多数语言中被读取为 int),它会得到完整的结果,因此您不会看到这种行为。

这在其他语言中也类似。

于 2013-07-03T17:37:18.510 回答
1

因为 0.7 和/或 0.1 在内部实际上是 0.6999999 .... 或 0.09 ...

这意味着您的 (0.7 * 0.1) 得出的结果更像 0.7999 ......乘以 10 和 int/flooring 后,您最终得到 7。

于 2013-07-03T17:37:37.567 回答
1

floor 函数向下舍入到最接近的整数。转换为 int 只会丢弃小数部分。 $foo是一个浮点数,它不完全是8,(必须是 7.99999...)所以你可以观察到这种行为。

于 2013-07-03T17:38:29.583 回答
1

如果分母包含的质因数不在基数的质因数列表中(即 2 和 5),则有理数将成为重复小数

  • 如果约化分数的分母包含一个不是基因数的质因数,则有理数具有无限重复序列,其长度小于完全约化分数的分母的值。如果约化分数也与基数共享一个素因子,则重复序列在小数点之后有一个有限长度的瞬态。

https://en.wikipedia.org/wiki/Repeating_decimal

计算机中的浮点类型几乎总是二进制,因此任何在有理表示中的分母不是 2 的幂的数都是无限周期十进制数。例如,在IEEE-754 单精度中,0.1 将四舍五入为0.100000001490116119384765625 ,这是 2s 的最接近的幂和

这里 0.7 和 0.1 都不能用二进制浮点表示,0.8 也不能。它们的总和也不等于 0.8:尝试打印0.7 + 0.1 == 0.8,你会得到错误的结果。它实际上略小于 0.8。但这不是像您一样的重复小数7.(9),而是小数部分中具有有限个 9 的值。

结果是ceilandint结果为 7。如果您取floororround结果,您将得到 8

于 2013-07-27T14:53:22.533 回答