数字之和返回奇数低位小数?

When summing a group of numbers sometimes I end up with some low decimals? Why can it happen when the numbers are parsed as strings? I know there is some %"&! about floats

function parse(){
    foreach($_SESSION['import_csv_posts']['result']['csv'] as $key => $post){
        $amount = $this->parse_amount($post[$this->param['amount']]);
        if($this->param['vat_amount']){
            $amount += $this->parse_amount($post[$this->param['vat_amount']]);
        }

        $this->balance += $amount;
        echo "$amount
";
    }

    echo "
balance = ".$this->balance;
}

function parse_amount($amount){
    $amount = strval($amount);
    if(strstr($amount, '.') && strstr($amount, ',')){
        preg_match('/^\-?\d+([\.,]{1})/', $amount, $match);
        $amount = str_replace($match[1], '', $amount);
    }

    return str_replace(',', '.', $amount);
}

result

-87329.00
-257700.00
-11400.00
-9120.00
-47485.00
-15504.00
122800.00
1836.00
1254.00
200.00
360.00
31680.00
361.60
1979.20
1144.00
7520.00
6249.49
balance = -399.00000000003

The "%"&! about floats" is that floats are simply not precise. There's a certain inaccuracy inherent in how infinite numbers are stored in finite space. Therefore, when doing math with floats, you won't get 100% accurate results.

Your choice is to either round, format numbers to two decimal places upon output, or use strings and the BC Math package, which is slower, but accurate.

Floating point arithmetic is done by the computer in binary, while the results are displayed in decimal. There are many numbers that cannot be represented equally precisely in both systems, therefore there is almost always some difference between what you as a human expect the result to be and what the result actually is when seen as bits (this is the reason that you cannot reliably compare floats for equality).

It does not matter that your numbers are produced through parsing strings, as soon as PHP sees an arithmetic operator it internally converts the strings to numbers.

If you do not require absolute precision (which it looks like you do not, as you are simply displaying stuff) then simply use printf with a format string such as %.2f to limit the number of decimal places.