我在代码中发现了一个错误。基本上我回到客户端的金额减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并且它似乎正在工作
答案 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/3
为0.33333....
。无论他们在十进制数字后面放多少3
,都无法准确地写出来。当且仅当m/n
的唯一素因子为10
和n
时,有理数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! ?>
此问题有多种解决方案:您可以使用number_format()
获取不带小数位的数字的字符串表示,然后使用intval()
获取整数值。
另一个解决方案是对round()
返回的值应用(int)
类型转换(但对于某些值,它可能不起作用)。