使用(int)
转换变量时,PHP似乎错误地舍入。为什么?
$multiplier = 100000000;
$value = 0.01020637;
echo (int)($value*$multiplier);
输出:1020636
。 (意外输出)
$multiplier = 100000000;
$value = 0.01020637;
echo ($value*$multiplier);
输出:1020637
。 (预期的正确输出)
编辑:情况变得更糟......
$multiplier = 100000000;
$value = 0.01020637;
echo $temp = ($value*$multiplier);
echo '<br/>';
echo (int)$temp;
输出:
1020637
1020636
答案 0 :(得分:2)
当您处理浮点数时,事情会变得毛茸茸,浮点数学(以及所涉及的问题)被很好地理解,但是当您不期待它们时会突然出现。似乎在这里发生过。您可以在the rules上广泛阅读,或在处理浮点运算时使用语言提供的工具。
当您关心所涉及的精度时,您应该使用bcmul()函数。这是一个“可选”的扩展,但是如果你关心精度,它会很快被开始需要。
示例:
multiplier = 100000000;
$value = 0.01020637;
echo (int)($value*$multiplier);
echo "\n";
echo bcmul($value, $multiplier, 0);
答案 1 :(得分:1)
float
投射到int
可能会产生无法预测的结果的原因。有关详细信息,请参阅PHP Integer页面。基本上,你在数学中得到的微小不精确,在尝试做ceil()
之类的事情时可能会导致严重的问题
如果您真的需要转换为int
的数字,我建议您先将数字四舍五入
$multiplier = 100000000;
$value = 0.01020637;
$temp = round($value*$multiplier);
echo $temp . '<br/>' . (int)$temp;
这可以通过截断小的浮点错误来实现。虽然bcmath也可以进行截断,但它不是PHP核心的一部分,也不是一个好的整体解决方案。你最好的选择是自己编写一个舍入程序,它可以返回你正在寻找的精度。在我工作的项目中,这就是我们所做的。我们编写了自己的舍入函数,它修复了您将遇到的问题。如果不知道你想要做什么的具体细节,很难说这是否是你需要的,但这就是我们如何在没有bcmath的情况下做到这一点。
答案 2 :(得分:0)
您遇到的问题如下: 将两个数字相乘时:
$mulitply = 0.1 * 100;
你没有将完全 100与0.1相乘,但与0.09999999998 ...
当涉及到(int)
时,它会将4.999
之类的数字转换为4
,因此在使用1020636.999999999
进行计数时,结果1020636
会变为(int)
。
答案 3 :(得分:0)
答案 4 :(得分:-1)
要在PHP中舍入浮点数,您应该使用 round()函数。只是转换为整数不会正确地舍入值。
第一个参数是舍入(在这种情况下计算的结果)舍入,第二个是可选的,并指定返回的小数(即精确度)。还有第三个参数,控制模式。这些可以是PHP_ROUND_HALF_UP,PHP_ROUND_HALF_DOWN,PHP_ROUND_HALF_EVEN或PHP_ROUND_HALF_ODD。
来自php.net/round的示例:
<?php
echo round(3.4); // 3
echo round(3.6); // 4
echo round(3.6, 0); // 4
echo round(1.95583, 2); // 1.96
// With the third element, "mode"
echo round(9.5, 0, PHP_ROUND_HALF_UP); // 10
echo round(9.5, 0, PHP_ROUND_HALF_DOWN); // 9
echo round(9.5, 0, PHP_ROUND_HALF_EVEN); // 10
echo round(9.5, 0, PHP_ROUND_HALF_ODD); // 9
?>
代码示例(live example):
<?php
$multiplier = 100000000;
$value = 0.01020637;
echo intval(round($value*$multiplier)); // Returns 1020637
?>