为什么 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
- 它是否在某处 defined/explained,此时它给出了 "round" 值?
- 有没有什么函数可以给出
0
小数点后有多少个 9?
舍入的不是 floor
,而是浮点数。
这一行:
echo 0.99999999999999999;
打印 1
(demo) 因为 0.99999999999999999
太精确而不能用(64 位?)浮点数表示,所以取最接近的可能值,这发生了成为 1
.
0.99999999999999994
也太精确了,无法准确表示,但这里最接近的可表示值恰好是 0.9999999999999999
.
- Is it defined/explained somewhere, at which point it gives "round" value?
这很复杂,但数字几乎总是四舍五入。
我相信没有 "from when values will be approximated" 的定义,但这是从 IEEE 754 floating point standard.
中的定义得出的数学 属性
为了安全起见,假设一切都是近似值。
- 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()
功能与此行为无关
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
- 它是否在某处 defined/explained,此时它给出了 "round" 值?
- 有没有什么函数可以给出
0
小数点后有多少个 9?
舍入的不是 floor
,而是浮点数。
这一行:
echo 0.99999999999999999;
打印 1
(demo) 因为 0.99999999999999999
太精确而不能用(64 位?)浮点数表示,所以取最接近的可能值,这发生了成为 1
.
0.99999999999999994
也太精确了,无法准确表示,但这里最接近的可表示值恰好是 0.9999999999999999
.
- Is it defined/explained somewhere, at which point it gives "round" value?
这很复杂,但数字几乎总是四舍五入。
我相信没有 "from when values will be approximated" 的定义,但这是从 IEEE 754 floating point standard.
中的定义得出的数学 属性
为了安全起见,假设一切都是近似值。
- 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()
功能与此行为无关