为什么 floor(0.99999999999999999) = 1 和 floor(0.9999999999999999) = 0?

Why floor(0.99999999999999999) = 1 and floor(0.9999999999999999) = 0?

PHP 中的 floor 函数行为异常。 对于 16 个十进制值,它给出了下限值,但通过增加 1 个小数点来舍入。

$int = 0.99999999999999999; 
echo floor($int); // returns 1 

$int = 0.9999999999999999; 
echo floor($int); // returns 0

$int = 0.99999999999999994; 
echo floor($int); // returns 0
  1. 它是否在某处 defined/explained,此时它给出了 "round" 值?
  2. 有没有什么函数可以给出 0 小数点后有多少个 9?

舍入的不是 floor,而是浮点数。

这一行:

echo 0.99999999999999999;

打印 1 (demo) 因为 0.99999999999999999 太精确而不能用(64 位?)浮点数表示,所以取最接近的可能值,这发生了成为 1.
0.99999999999999994 也太精确了,无法准确表示,但这里最接近的可表示值恰好是 0.9999999999999999.

  1. Is it defined/explained somewhere, at which point it gives "round" value?

这很复杂,但数字几乎总是四舍五入。
我相信没有 "from when values will be approximated" 的定义,但这是从 IEEE 754 floating point standard.
中的定义得出的数学 属性 为了安全起见,假设一切都是近似值。

  1. Is there any function which gives 0 anyhow how many 9 in decimals?

没有。问题是,对于 PHP,0.99999999999999999 在字面上与 1.
相同 它们由完全相同的位序列表示,因此无法区分它们。

有一些解决方案可以处理更高精度的小数,但这需要对代码进行一些重大更改。
您可能感兴趣:

Working with large numbers in PHP

请注意,虽然您可以获得 任意 精度,但您永远不会获得 无限 精度,因为这需要无限量的存储空间。

另请注意,如果您实际上处理无限精度,0.999...(永远持续)将是真正 (如数学上可证明的)等于 1,如 this Wikipedia article.

中的深入解释
$float_14_digits = 0.99999999999999;
echo $float_14_digits; // prints 0.99999999999999
echo floor($float_14_digits); // prints 0

$float_15_digits = 0.999999999999999;
echo $float_15_digits; // prints 1
echo floor($float_15_digits); // prints 1
exit;

在我的开发机器上,行为发生在数字“15”上,而不是像你的那样发生在“17”上。 PHP 将浮点数的最后一位四舍五入。您的 floor() 功能与此行为无关