PHP – błąd zaokrąglania podczas rzutowania liczb

Logo PHP7

Dzisiaj opiszę jedną sytuację która mi się nie dawno zdarzyło. Co prawda już wcześniej teoretycznie wiedziałem, że takie coś może się stać, ale po prostu zanim w praktyce mi się to nie zdarzyło, nie pamiętałem o tym.

Spróbuj uruchomić poniższe polecenie w pliku PHP:

echo(intval(19.9 * 100));

Co wyświetla? 1989. A przecież wydaje się, że powinno 1990.

U mnie ten błąd rzutowania się pojawił w jednym ze skryptów ogłoszeniowych w czasie zapisywania ceny do bazy danych:

$sth->bindValue(':price', ($price*100), PDO::PARAM_INT);

Użytkownik wpisywał cenę 19,90 a do bazy zapisywało się 1989.

Z czego wynika ta różnica?

Otóż to nie jest błąd. Komputery nie mają możliwości dokładnego przedstawienia liczb zmiennoprzecinkowych. Mogą je zbliżyć tylko do określonej precyzji. Ilekroć robisz coś, co wymaga absolutnej precyzji, musisz wziąć to pod uwagę. 2,3 * 100 nigdy nie będzie dokładnie 230. Będzie to 229,9999999999999999999 lub 230.0000000000000001, a jeśli wtedy wykonasz

(int) 229,99999999999999999;

dostaniesz 229.

A więc jak rozwiązać ten problem?

Chyba najprostsze rozwiązanie to skorzystanie z funkcji round() w ten sposób:

echo(intval(round(19.9 * 100)));

Dostajemy wtedy poprawny wynik 1990. W moim kodzie musiałem dodać:

$sth->bindValue(':price', round($price*100), PDO::PARAM_INT);

Mam nadzieje, że ten wpis Wam pomoże gdy zetkniecie się z podobnym problemem.

Ta strona używa ciasteczek (cookies), dzięki którym nasz serwis może działać lepiej. Więcej informacji

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close