PHP:意外的变量比较结果.可能存在舍入问题


PHP: Unexpected variable comparison result. Possible rounding issue

我正在使用多个支付系统,其中一些系统处理没有小数点的付款,另一些系统使用小数点。我的价格存储时没有小数点,必要时我会进行转换。我有一个浮动的支付比例,在下面的代码中定义;例如1年可以以12.99美元购买,5年可以以29.99美元购买。当用户选择两年选项时,我的代码会出现错误。

下面是一些示例代码,它说明了我在网站上遇到的问题。每当用户选择两年定价时,$years变量都不会定义,并且会引发错误。我不知道为什么所有其他定义的年份值在测试时都是真的,但1999年的数字却不是。我们非常感谢对这个问题的任何想法。以下示例代码的输出如下:

1,错误,3,4,5,

<?php
define('year1', 1299);
define('year2', 1999);
define('year3', 2499);
define('year4', 2799);
define('year5', 2999);
$prices = array_values(array('YearOne' => 12.99, 'YearTwo' => 19.99, 'YearThree' => 24.99, 'YearFour' => 27.99, 'YearFive' => 29.99));
for ($x = 0; $x < sizeof($prices); $x++) {
$proPrice = $prices[$x] * 100;
switch ($proPrice) {
    case year1:
        $years = 1;
        break;
    case year2:
        $years = 2;
        break;
    case year3:
        $years = 3;
        break;
    case year4:
        $years = 4;
        break;
    case year5:
        $years = 5;
        break;
    default:
        $years = 'Error';
}
echo $years . ', ';
}
?>

如果我将$proPrice = $prices[$x] * 100;更改为$proPrice = round($prices[$x] * 100,0);,我将不再有意外的结果,但我想知道为什么对1999值使用round函数是必要的,而不是其他函数。

这个问题是由浮点数引起的,请参阅PHP手册中的大警告。

您可以使用bcmul,结果如预期,请参阅下面的示例:

define('year1', 1299);
define('year2', 1999);
define('year3', 2499);
define('year4', 2799);
define('year5', 2999);
$prices = array_values(array('YearOne' => 12.99, 'YearTwo' => 19.99, 'YearThree' => 24.99, 'YearFour' => 27.99, 'YearFive' => 29.99));
$length = sizeof($prices); //taking it out from loop comparison, as there is no need to get the size of array, which isn't changing.
for ($x = 0; $x < $length; $x++) {
$proPrice = bcmul($prices[$x],100);
switch ($proPrice) {
    case year1:
        $years = 1;
        break;
    case year2:
        $years = 2;
        break;
    case year3:
        $years = 3;
        break;
    case year4:
        $years = 4;
        break;
    case year5:
        $years = 5;
        break;
    default:
        $years = 'Error';
}
echo $years . ', ';
}