Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/232.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP中的浮点数--奇怪的行为_Php_Floating Point_Floating Accuracy - Fatal编程技术网

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

PHP中的浮点数--奇怪的行为,php,floating-point,floating-accuracy,Php,Floating Point,Floating Accuracy,有人能解释一下这里发生了什么吗?我有一个浮点数,要四舍五入到两个小数点(价格) 输出为: 79.95四舍五入为79.95 79.9500000000000028421709430404007434844970703125四舍五入为79.95000000284217094304040074348449703125 所以,“回声”会自动循环。当我使用var_export()输出数据时,round()似乎不起作用 为了测试,我做了: $total = 79.9501234576908988888;

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

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

所以,“回声”会自动循环。当我使用var_export()输出数据时,round()似乎不起作用

为了测试,我做了:

$total = 79.9501234576908988888;
然后我得到: 79.950123457691四舍五入为79.95 79.9501234576908927920158021152019500732421875四舍五入为79.9500000000000028421709430404007434844970703125

所以,“echo”似乎会自动将浮点舍入到11个小数点。为什么round()不使用var_导出是个谜

有人有解释吗

谢谢


鲁道夫

浮点数具有特定的、有限的精度。尽管取决于系统,PHP通常使用IEEE 754双精度格式,由于舍入的顺序为1.11e-16,因此会产生最大相对误差

在本例中,如果使用var_export,它将输出(或返回)变量的可解析字符串表示形式,在本例中,当您的数据存储为浮点变量时,它还将返回所有数据

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

var_export(round((float)$total,2));
系统将首先将$total四舍五入到79.95,但是由于您指定了float cast,它将存储到系统的数据精度,因此当您使用var_导出忠实地返回数据时,它将为您提供如下信息

79.9500000000000028421709430404007434844970703125

另一方面,PHP var_导出函数足够智能,可以区分您试图解析的数据类型。(即使不使用浮动铸造)。因此,如果解析“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.123000000000046611603465862572193145751953125四舍五入为79.120000000000004547350886411895751953125

变量导出()的四舍五入方式取决于PHP版本和系统设置“序列化精度”。您可以通过以下方式显示设置:

var_dump(ini_get('serialize_precision'));
如果你的权利允许,你可以

ini_set('serialize_precision',"-1");
改变这个。“-1”表示将使用改进的算法对这些数字进行四舍五入


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

Hmm。。但我在四舍五入之前先进行浮点运算,所以应该得到79.9500000000000000000。另外,省略cast to float不会改变行为。稍后我会给你更多信息。很抱歉,我在metro,所以我需要时间写一个更详细的解释。请看我修改过的答案谢谢你的解释。我做了阅读和测试。INI设置“serialize_precision”是导致该行为的原因。所以现在我知道了为什么会这样,我可以修复这个系统,让它工作。(不,我不打算更改设置,但这对于理解问题非常重要)是的,据我所知,这是许多服务器中使用的默认精度,但如果您愿意,可以覆盖它。很高兴知道你已经进入了下一个阶段。快乐的编码兄弟!您正在使用哪个PHP版本。还是PHP5.x?是的,谢谢。我不知道这个设置。现在,我做了更多的阅读和游戏设置要做的事情:概念验证“,这一切都是有意义的
ini_set('serialize_precision',"-1");