根据计算:(14056567 /(14056567/100)),这等于浮点数100。 在浮点数100上使用PHP floor()应始终返回100。
但这是我的问题:当输入浮点数100是除法的结果时,floor()返回99.
测试1:
<?php
$test = (14056567/(14056567/100));
var_dump($test);
$test = floor($test);
var_dump($test);
// output:
// float(100)
// float(99)
测试2:
<?php
$test = (14056567/(14056567/100));
$test = (double)$test;
$test = (float)$test;
$test = floatval($test);
$test = 0 + $test;
var_dump($test);
$test = floor($test);
var_dump($test);
// output:
// float(100)
// float(99)
测试3:
<?php
$test = (14056567/(14056567/100));
$test = floatval('' . $test);
var_dump($test);
$test = floor($test);
var_dump($test);
// output:
// float(100)
// float(100)
所以只有当连接一个字符串和我的浮点数时,它才会在一个floor()之后给出我期望的结果。
根据以下链接中的回复:https://bugs.php.net/bug.php?id=6851 原因是100等于99.999999的浮点数,即使这是真的,为什么在不是除法的结果时不是这种情况呢?
答案 0 :(得分:3)
14056567/100 = 140565.67
对人类来说很好,因为我们使用十进制,计算机使用二进制,而.67并不能很容易地用二进制表示(我甚至不能100%确定它是否可以完全代表那个数字,即使是完美的精确度。)
如果您为其生成十六进制,结果类似于0.ab851eb851eb88
,但0.ab851eb851eb88
实际上是0.670,000,000,02
附近的数字。
按此近似值进行除法时,得到的数字最好表示为100,但实际上更像是99.999,999,999,98
,当您调用var_dump
时会显示该数字关闭。
当你打电话给它时,它会给你99个,因为floor(99.9999999)
实际应该生成什么,100的答案是四舍五入的结果,楼层的结果对于你的数字是正确的#39 ;重新使用。
答案 1 :(得分:2)
尝试使用以下脚本查看最新情况:
<?php
printf ("# No precision lost\n");
printf ("14056567.0 = %.53f\n\n", 14056567.0);
printf ("# No precision lost\n");
printf ("100.0 = %.53f\n\n", 100.0);
printf ("# Precision lost, because 140565.67 can't be represented precisely in float\n");
printf ("14056567.0/100.0 = %.53f\n\n", 14056567.0 / 100.0);
printf ("# Same here without division\n");
printf ("140565.67 = %.53f\n\n", 140565.67);
printf ("# Lost precision carrying on...\n");
printf ("14056567.0/140565.67 = %.53f\n\n", 14056567.0 / 140565.67);
printf ("# This is OK\n");
printf ("14056567.0*100.0/14056567.0 = %.53f\n\n", 14056567.0 * 100.0 / 14056567.0);
// Output:
// # No precision lost
// 14056567.0 = 14056567.00000000000000000000000000000000000000000000000000000
//
// # No precision lost
// 100.0 = 100.00000000000000000000000000000000000000000000000000000
//
// # Precision lost, because 140565.67 can't be represented precisely in float
// 14056567.0/100.0 = 140565.67000000001280568540096282958984375000000000000000000
//
// # Same here without division
// 140565.67 = 140565.67000000001280568540096282958984375000000000000000000
//
// # Lost precision carrying on...
// 14056567.0/140565.67 = 99.99999999999998578914528479799628257751464843750000000
//
// # This is OK
// 14056567.0*100.0/14056567.0 = 100.00000000000000000000000000000000000000000000000000000
?>