PHP Adding 2 decimal points numbers (money) gives wrong results in total amount

后端 未结 7 538
傲寒
傲寒 2021-01-13 00:30

I have an customer invoice table in my MySQL database with a DECIMAL(10,2) field called price.

When fetching these values in php and calculating a sum amount,

相关标签:
7条回答
  • 2021-01-13 01:06

    have you tried to

    round(totalAmount, 2, PHP_ROUND_HALF_ODD);
    

    it should see last decimal number - if it's odd - rounds down, if even - up

    0 讨论(0)
  • 2021-01-13 01:07

    I recommend doing calculations on SQL Level with queries or views.

    Firstly, using 64 bit integers on PHP is risky because; on overflow, it switches to float and you lose precision. When it's money, the problem is more serious. You should acually calculate a column with sql and just get the value from there. Money is a long type and it will often convert to float on php and your people will lose or win some cents depending on the mood of php engine. You can't work with decimal type on php, even if you multiply by 100 and keep it as an integer, long numbers with overflow will be converted to float automatically. Calculate your values on MYSQL if you want to use decimal numbers or convert your field into int.

    If your server has an 32 bit cpu, the WORD length is 32 bit so integers in php engine are 32 bit integers. This makes the likelihood of overflow higher. On an 64 bit system, you can work more comfortably.

    Using a round function on a money value is ridiculous and unprofessional in this case. Don't do it.

    Reading this document will help you a lot.

    php documentation of integers says

    Integer overflow

    If PHP encounters a number beyond the bounds of the integer type, it will be interpreted as a float instead. Also, an operation which results in a number beyond the bounds of the integer type will return a float instead.

    Calculation on SQL level will ensure precision for money type. Getting the money type to php will result in a float value, and you can multiply it by 100 and divide by 100 later BUT it increases the rish of overflow again because php will use an 32 bit float number for storage. If you are using 32 bit float why is the data field decimal? So it's inconsistent if you do that. an 32 bit number i already not so big, and an 32 bit float loses some of its capacity on floating point, so it's more likely to reach over capacity when you multiply by 100.

    USE SQL

    0 讨论(0)
  • 2021-01-13 01:09

    Indeed, floating point numbers are not precise.
    Either calculate in cent (multiply by 100 and calculate in integers), or calculate in strings using BC Math.

    0 讨论(0)
  • 2021-01-13 01:10

    If you need accuracy of 2 decimal points:

    1. multiply value by 100
    2. do your operations
    3. divide by 100 and use number_format where appropriate
    0 讨论(0)
  • 2021-01-13 01:11

    Try this:

    $totalAmount = number_format($totalAmount, 2, '.', '');
    
    0 讨论(0)
  • 2021-01-13 01:14

    Well, to begin with, why sum in a php loop when you can do that in mysql? Moreover, just use integer multiplied by 100 and then divide by 100 once you need the final result.

    0 讨论(0)
提交回复
热议问题