Dlaczego 0.1 + 0.2 nie równa się 0.3
Wpisz to działanie w konsoli przeglądarki, a zobaczysz 0.30000000000000004. To nie błąd przeglądarki ani JavaScriptu — tak liczy prawie każdy komputer na świecie.
Otwórz konsolę w przeglądarce i wpisz 0.1 + 0.2. Wynik: 0.30000000000000004. Ten sam wynik dostaniesz w Pythonie, w Javie, w C i w arkuszu kalkulacyjnym. To nie usterka, tylko konsekwencja tego, jak komputer zapisuje ułamki.
Jedna trzecia w systemie dziesiętnym
Spróbuj zapisać jedną trzecią dziesiętnie: 0,333333… Ciągnie się w nieskończoność. Jeśli masz miejsce na dziesięć cyfr, zapiszesz przybliżenie. Pomnóż je przez trzy, a dostaniesz 0,999999999 — nie jedynkę.
Komputer ma dokładnie ten sam problem, tylko w systemie dwójkowym. W nim nieskończenie rozwija się między innymi 0,1. Zapisywana jest więc najbliższa możliwa wartość, odrobinę różna od dokładnej jednej dziesiątej. Zsumuj dwa takie przybliżenia i błąd staje się widoczny.
Kiedy to naprawdę boli
Przy wyświetlaniu temperatury nikt nie zauważy. Przy pieniądzach — owszem. Klasyczny scenariusz: sto pozycji po 0,10 zł, a suma wychodzi 9,999999999999998 zł i po zaokrągleniu w górę różni się o grosz od tego, co policzył księgowy.
Równie zdradliwe jest porównywanie:
if (0.1 + 0.2 == 0.3) {
// ten kod nigdy się nie wykona
}
Jak sobie z tym radzić
Pieniądze trzymaj w groszach, jako liczby całkowite. Nie 19,99 zł, tylko 1999. Liczby całkowite komputer zapisuje idealnie, więc żaden błąd się nie pojawi. Dzielisz przez sto dopiero przy wyświetlaniu.
W bazie danych oznacza to kolumnę typu DECIMAL(10,2) albo INT na grosze — nigdy FLOAT ani DOUBLE dla kwot.
Ułamków nigdy nie porównuj przez równość. Sprawdzaj, czy różnica jest dostatecznie mała:
if (Math.abs(a - b) < 0.000001) {
// dla naszych potrzeb to ta sama liczba
}
Zaokrąglaj raz, na końcu. Zaokrąglanie po każdym kroku kumuluje błędy zamiast je usuwać.
Komputer nie jest w liczeniu nieomylny. Jest tylko bardzo szybki i bardzo konsekwentny.
Ciekawostka na koniec: standard opisujący ten sposób zapisu liczb powstał w 1985 roku i nazywa się IEEE 754. Ma czterdzieści lat, siedzi w każdym procesorze na świecie i to jego zachowanie oglądasz w konsoli przeglądarki.
Komentarze (6)
-
Jarek
Sprawdziłem w konsoli w trakcie czytania i faktycznie. Trzydzieści lat przy komputerze i nigdy się nad tym nie zastanawiałem.
Odpowiedz -
Jarek
Sprawdziłem w konsoli w trakcie czytania i faktycznie. Trzydzieści lat przy komputerze i nigdy się nad tym nie zastanawiałem.
Odpowiedz -
Agnieszka
Rada o trzymaniu kwot w groszach jest złota. Przerobiliśmy tak cały moduł rozliczeń i różnice groszowe w raportach po prostu zniknęły.
Odpowiedz