我在PHP程序中有两个变量用于账单,$ charge和$ payments。
$charges
是任何付款前应付的总金额。 $payments
是收到的总金额。
我按照这样的方式计算余额:
$balance_due = $charges-$payments;
简单,除了我得到以下结果:
$balance_due has -9.0949470177293E-13 for a value (expecting 0).
$ charge和$ payments的值均为5511.53。
当我var_dump($charges)
和var_dump($payments)
时,他们都显示:float(5511.53)
此代码(和===):
if($charges == $payments){
error_log('they are the same');
}else{
error_log('they are not the same');
}
都会导致错误。
如果我硬编码:$ charge = $ payments = 5511.53;并按预期运行$ balance_due = 0。
我很困惑。我错过了什么?
编辑说明
我能够使用我在BC Math Functions页面上找到的氮的用户贡献函数,以便提出以下解决方案:
if(Comp($charges, $payments)===0){
$balance_due = 0;
}else{
$balance_due = ( $charges - $payments );
}
function Comp($Num1,$Num2,$Scale=null) {
// check if they're valid positive numbers, extract the whole numbers and decimals
if(!preg_match("/^\+?(\d+)(\.\d+)?$/",$Num1,$Tmp1)||
!preg_match("/^\+?(\d+)(\.\d+)?$/",$Num2,$Tmp2)) return('0');
// remove leading zeroes from whole numbers
$Num1=ltrim($Tmp1[1],'0');
$Num2=ltrim($Tmp2[1],'0');
// first, we can just check the lengths of the numbers, this can help save processing time
// if $Num1 is longer than $Num2, return 1.. vice versa with the next step.
if(strlen($Num1)>strlen($Num2)) return(1);
else {
if(strlen($Num1)<strlen($Num2)) return(-1);
// if the two numbers are of equal length, we check digit-by-digit
else {
// remove ending zeroes from decimals and remove point
$Dec1=isset($Tmp1[2])?rtrim(substr($Tmp1[2],1),'0'):'';
$Dec2=isset($Tmp2[2])?rtrim(substr($Tmp2[2],1),'0'):'';
// if the user defined $Scale, then make sure we use that only
if($Scale!=null) {
$Dec1=substr($Dec1,0,$Scale);
$Dec2=substr($Dec2,0,$Scale);
}
// calculate the longest length of decimals
$DLen=max(strlen($Dec1),strlen($Dec2));
// append the padded decimals onto the end of the whole numbers
$Num1.=str_pad($Dec1,$DLen,'0');
$Num2.=str_pad($Dec2,$DLen,'0');
// check digit-by-digit, if they have a difference, return 1 or -1 (greater/lower than)
for($i=0;$i<strlen($Num1);$i++) {
if((int)$Num1{$i}>(int)$Num2{$i}) return(1);
else
if((int)$Num1{$i}<(int)$Num2{$i}) return(-1);
}
// if the two numbers have no difference (they're the same).. return 0
return(0);
}
}
}
该解决方案对我有用。下面的imtheman提供的答案也有效,看起来效率更高,所以我将使用那个。 有没有理由不使用其中一种?
答案 0 :(得分:3)
当我遇到它时,我解决这个问题的方法是使用php的number_format()
。来自php documentation:
string number_format(float $number [, int $decimals = 0 ])
所以我会这样做:
$balance_due = number_format($charges-$payments, 2);
这应该可以解决你的问题。
注意:number_format()
会返回一个字符串,因此要进行比较,您必须先使用==
(不是===
)或在比较之前将其强制转换为(float)
。< / p>