Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Nieprawidłowa precyzja dziesiętna MySQL i PHP

Od artykuł, który napisałem dla Authorize.Net :

Jeden plus jeden równa się dwa, prawda? Co powiesz na 0,2 plus 1,4 razy 10? To równa się 16, prawda? Nie, jeśli robisz matematykę z PHP (lub większością innych języków programowania):

echo floor((0.2 + 1.4) * 10); // Should be 16. But it's 15!

Wynika to z wewnętrznego sposobu obsługi liczb zmiennoprzecinkowych. Są one reprezentowane przez stałą liczbę miejsc po przecinku i mogą skutkować liczbami, które nie sumują się tak, jak się spodziewasz. Wewnętrznie nasz przykład 0,2 plus 1,4 razy 10 oblicza z grubsza 15.99999999998 lub coś koło tego. Ten rodzaj matematyki jest dobry podczas pracy z liczbami, które nie muszą być dokładne, jak procenty. Ale podczas pracy z pieniędzmi precyzja ma znaczenie, ponieważ brakujący grosz lub dolar szybko się sumuje i nikt nie lubi tracić pieniędzy.

Rozwiązanie matematyczne BC

Na szczęście PHP oferuje rozszerzenie BC Math czyli "dla matematyki o dowolnej precyzji, PHP oferuje Kalkulator Binarny, który obsługuje liczby o dowolnej wielkości i precyzji, reprezentowane jako łańcuchy." Innymi słowy, za pomocą tego rozszerzenia możesz wykonać dokładną matematykę z wartościami pieniężnymi. Rozszerzenie BC Math zawiera funkcję s, które umożliwiają precyzyjne wykonywanie najczęstszych operacji, w tym dodawanie , odejmowanie , mnożenie i podział .

Lepszy przykład

Oto ten sam przykład, co powyżej, ale używając funkcji bcadd() do wykonania obliczeń za nas. Zajmuje trzy parametry. Pierwsze dwie to wartości, które chcemy dodać, a trzecia to liczba miejsc po przecinku, do których chcemy być dokładni. Ponieważ pracujemy z pieniędzmi, ustawimy precyzję na dwa miejsca po przecinku.

echo floor(bcadd('0.2', '1.4', 2) * 10); // It's 16 like we would expect it to be.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Eksportuj bazę danych MySQL/MariaDB

  2. Zwiększone wartości kolumn aktualizacji MySQL (bez automatycznej inkrementacji)

  3. Zatrzymaj ponowne używanie przez MySQL identyfikatorów AUTO_INCREMENT

  4. PHP/MySQL:Najlepsze praktyki w zakresie operacji/przechowywania pieniędzy?

  5. Jak wyeksportować dane z SQL Server 2005 do MySQL