PHP向下舍入规则

时间:2017-07-24 08:08:41

标签: php

我在代码中发现了一个错误。基本上我回到客户端的金额减1美分,我发现这是由于int铸造。有人可以解释为什么会这样吗?

$x = 9.53 * 100;

var_dump($x); // double(953)
var_dump((int)$x); // int(952)

此外,我发现所有情况都没有发生这种情况。 例如:

echo (int)(9.52 * 100)//952
echo (int)(9.53 * 100)//952
echo (int)(9.54 * 100)//953
echo (int)(9.55 * 100)//955

我对这个问题的解决方案是首先进行计算并将其转换为int并将其转换为int并且它似乎正在工作

2 个答案:

答案 0 :(得分:4)

这不是错误,这是因为浮动数字的表示。

在内存中,9.53 正好9.53,请使用printf查看:

$y = 9.53;
printf("%.25f\n", $y);
$x = 9.53 * 100;
printf("%.25f\n", $x);

<强>输出:

9.5299999999999993605115378
952.9999999999998863131622784

答案 1 :(得分:1)

  

有人可以解释为什么会这样吗?

在计算机中,实际数字并未准确存储。它们是近似值。

在现实生活中,以10为基础进行计算,1/30.33333....。无论他们在十进制数字后面放多少3,都无法准确地写出来。当且仅当m/n的唯一素因子为10n时,有理数2在基数5中的有效表示为十进制比率基数的主要因素)。

在计算机中,所有内容都使用基础2存储。这意味着在基数10中具有有限表示的大多数数字(如9.53)在基数2中没有有限表示,并且实际存储了它们的近似值

9.53乘以100并没有多大帮助。由于初始错误,结果是953的近似值。由于它小于953(int)(9.53*100)会产生952

您的情况已经在PHP手册页中记录了integers

  

警告

     

永远不要将未知分数投射到integer,因为这有时会导致意外结果。

 <?php
 echo (int) ( (0.1+0.7) * 10 ); // echoes 7!
 ?>
     

另请参阅warning about float precision

此问题有多种解决方案:您可以使用number_format()获取不带小数位的数字的字符串表示,然后使用intval()获取整数值。

另一个解决方案是对round()返回的值应用(int)类型转换(但对于某些值,它可能不起作用)。