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
- 它是否在某个地方定义/解释,在哪个点它给出"圆"值?
- 是否有任何函数可以给出
0
,无论如何,小数中有多少9 ?
不是floor
的四舍五入,而是浮点数的四舍五入
:
echo 0.99999999999999999;
打印1
(demo),因为0.99999999999999999
太精确了,不能用(64位?)浮点数表示,所以取最接近的值,碰巧是1
。0.99999999999999994
也太精确了,无法精确地表示,但这里最接近的可表示值恰好是0.9999999999999999
。
- 它是否在某个地方定义/解释,在哪个点它给出"圆"值?
这很复杂,但这些数字几乎都是四舍五入的。
我相信没有"从何时开始逼近值"的定义,但这是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()
函数与此行为无关