PHP 中的浮点数 -- 奇怪的行为

Floating point numbers in PHP -- strange behaviour

有人可以解释这里发生了什么吗?我有一个浮点数,要四舍五入到小数点后两位(价格)。

echo $total . " is rounded to " . round((float)$total,2);
var_export((float)$total);
echo " is rounded to ";
var_export(round((float)$total,2));
echo "\r\n";

输出为: 79.95 四舍五入为 79.95 79.9500000000000028421709430404007434844970703125 四舍五入为 79.9500000000000028421709430404007434844970703125

因此,“echo”舍入到自身。当我使用 var_export() 输出数据时,似乎 round() 不起作用。

为了测试,我做了:

$total = 79.9501234576908988888;

然后我得到: 79.950123457691 四舍五入为 79.95 79.9501234576908927920158021152019500732421875 四舍五入为 79.9500000000000028421709430404007434844970703125

因此,“echo”似乎会自动将浮点数舍入到小数点后 11 位。为什么 round() 不适用于 var_export 是个谜。

有人解释一下吗?

谢谢,

鲁道夫

浮点数具有特定的、有限的精度。尽管它取决于系统,但 PHP 通常使用 IEEE 754 双精度格式,由于按 1.11e-16 的顺序舍入,这将给出最大相对误差。

在您的情况下,如果您使用 var_export,它将输出(或 return)变量的可解析字符串表示形式,在这种情况下,它还将 return 所有当您的数据存储为浮点变量时的数据。

这就是为什么当你执行以下命令时

var_export(round((float)$total,2));

系统会先将$total四舍五入到79.95,但是因为你指定了float cast,它会按照系统的数据精度存储它,所以当你使用var_export忠实地return 数据,它会给你类似的东西

79.9500000000000028421709430404007434844970703125

另一方面,PHP var_export 函数足够智能,可以区分您要解析的数据类型。 (即使你不使用浮动演员)。因此,如果你解析“79”,该值将被视为整数,如果你解析“79.123”,该值将被视为浮点数。

说下代码:

<?php
//$total = 79.9501234576908988888;
$total = 79;

echo "parsing 79";
echo "<br>";

var_export((float)$total);
echo " is rounded to ";
var_export(round((float)$total,2));
echo "<br><br>";

$total = 79.123;

echo "parsing 79.123";
echo "<br>";


var_export($total);
echo " is rounded to ";
var_export(round($total,2));
echo "<br><br>";



?>

结果将是:

正在解析 79

79 四舍五入为 79

正在解析 79.123

79.12300000000000046611603465862572193145751953125 四舍五入为 79.1200000000000045474735088646411895751953125

var_export() 如何四舍五入取决于 PHP 版本和系统设置 'serialize_precision'。您可以显示设置:

var_dump(ini_get('serialize_precision'));

如果您的权利允许,您可以

ini_set('serialize_precision',"-1");

改变这个。 “-1”表示将使用增强算法对此类数字进行舍入。

该指令必须始终位于脚本的开头,或者您可以更改 php.ini 中的设置。