Why floor(0.99999999999999999) = 1 and floor(0.9999999999999


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

PHP底层函数的行为很奇怪。对于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. 它是否在某个地方定义/解释,在哪个点它给出"圆"值?
  2. 是否有任何函数可以给出0,无论如何,小数中有多少9 ?

不是floor的四舍五入,而是浮点数的四舍五入

这条线

:

echo 0.99999999999999999;

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

  1. 它是否在某个地方定义/解释,在哪个点它给出"圆"值?

这很复杂,但这些数字几乎都是四舍五入的。
我相信没有"从何时开始逼近值"的定义,但这是IEEE 754浮点标准中定义的数学属性。为了安全起见,假设所有的东西都是近似的。

  • 是否有任何函数给出0无论如何有多少9在小数?
  • 。问题是,对于PHP, 0.99999999999999999字面上与1相同。
    它们由完全相同的位序列表示,因此无法区分它们。

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

    在PHP中使用大数

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

    还要注意,如果实际上是处理无限精度,那么0.999...(永远持续下去)将是真正的(在数学上是可证明的)等于1,这在这篇维基百科文章中有深入的解释。

    $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()函数与此行为无关