此问题最好用代码表示:
$var1 = 286.46; // user input data
$var2 = 3646; // user input data
$var3 = 25000; // minumum amount allowed
$var4 = ($var1 * 100) - $var2; // = 250000
if ($var4 < $var3) { // if 250000 < 250000
print 'This returns!';
}
var_dump($var4)
输出:float(25000)
,当转换为int时,输出:int(24999)
- 从而解决问题。
我真的不知道该怎么办。这个问题在乘以100时会发生,虽然我可以做很少的技巧来解决这个问题(例如* 10 * 10)但我想知道是否有一个“真正的”解决方案来解决这个问题。
谢谢:)
答案 0 :(得分:1)
这是一个可怕的hacky解决方案,我有点讨厌自己,但这给出了预期的行为:
<?php
$var1 = 286.46; // user input data
$var2 = 3646; // user input data
$var3 = 25000; // minumum amount allowed
$var4 = ($var1 * 100) - $var2; // = 250000
if ((string) $var4 < (string) $var3) { // if 250000 < 250000
print 'This returns!';
}
将它们转换为字符串,然后根据需要将它们转换回int / float以进行比较。我不喜欢它,但确实有效。
在PHP中,你需要BC Math来获得精确的浮点数学。
答案 1 :(得分:1)
当使用float number作为int时,使用ceil(或基于你想要的地板)总是一个好主意 在你的情况下,在比较之前尝试ceil($ var4)!
答案 2 :(得分:0)
浮游生物有时会发生这种情况,这完全是由于浮标不时无法准确表示整数。
您可以将数字舍入为整数值,然后将其转换为int,而不是将其转换为int。 (这可能是不必要的,但PHP并不清楚这些事情是如何在内部发生的,即使你现在知道它们是如何发生的,也可能在将来不会发生。
答案 3 :(得分:0)
我认为您可以使用bccomp来比较浮点值,但我认为这是一个不在PHP Core中的函数。
否则我发现这个函数here但我无法测试它是否有效
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);
}
}
}
答案 4 :(得分:0)
问题是花车不能代表一些数字。由于PHP没有“十进制”(或其他定点)类型,因此基本上只能解决这些问题。
假设示例$var1 = 286.46
中的第一个数字表示某种货币,您可以在用户输入后直接将其转换为美分(例如,通过剥离点并将其作为整数读取)从而计算一切都使用整数数学。
这不是一般的解决方案 - 而且我怀疑是否存在(缺少使用任意精度数字,这是一些PHP扩展提供的 - 但我闻起来像是有点过分了。)