Dokładność obliczeń LibreOffice

Nieodłączny problem z dokładnością

LibreOffice Calc, podobnie jak większość innych programów do obsługi arkuszy kalkulacyjnych, wykorzystuje funkcje matematyczne zmiennoprzecinkowe dostępne na sprzęcie. Biorąc pod uwagę, że większość współczesnego sprzętu wykorzystuje binarną arytmetykę zmiennoprzecinkową z ograniczoną precyzją zdefiniowaną w standardzie IEEE 754, wiele liczb dziesiętnych — w tym tak proste jak 0,1 — nie można dokładnie przedstawić w programie LibreOffice Calc (który wewnętrznie używa 64-bitowych liczb o podwójnej precyzji).

Obliczenia z użyciem tych liczb nieuchronnie prowadzą do błędów zaokrągleń, które kumulują się przy każdym obliczeniu.

Nie jest to błąd oprogramowania ani nic nieoczekiwanego, czego można by dzisiaj uniknąć bez konieczności stosowania skomplikowanych obliczeń programowych, które stawiałyby niedopuszczalnie nieproporcjonalne wymagania dotyczące wydajności. Użytkownicy muszą to uwzględnić i w razie potrzeby zastosować zaokrąglenia i porównania za pomocą epsilonu maszynowego (lub zaokrąglenia jednostek).

Przykład z liczbami:

A

1

31000.99

2

32000.12

3

=A1-A2


Spowoduje to wyświetlenie -999,129999999997 w komórce A3 zamiast oczekiwanego -999,13 (aby to zobaczyć, może być konieczne zwiększenie liczby wyświetlanych miejsc dziesiętnych w formacie komórki).

Przykład z datami i godzinami:

Ze względu na specyfikę reprezentacji godzin w programie Calc, dotyczy to również wszystkich obliczeń obejmujących godziny. Na przykład komórki A1 i A2 poniżej pokazują wprowadzoną datę i godzinę (w formacie ISO 8601):

A

1

2020-04-13 12:18:00

2

2020-04-13 12:08:00

3

=A1-A2


Komórka A3 wyświetli 00:10:00, jeśli do komórki zostanie zastosowane domyślne formatowanie [HH]:MM:SS. Jednak komórka A3 wyświetli 00:09:59.999999 zamiast oczekiwanej 00:10:00.000000, jeśli jest sformatowana przy użyciu ciągu formatu [HH]:MM:SS.000000. Dzieje się tak pomimo tego, że użyto tylko liczb całkowitych godzin i minut, ponieważ wewnętrznie każda godzina jest ułamkiem dnia, a godzina 12:00 (południe) jest reprezentowana jako 0,5.

Dane w komórkach są wewnętrznie reprezentowane jako 43934,5125 w A1 i jako 43934,5055555555591126903891563 w A2 (co nie jest dokładną reprezentacją wprowadzonych danych, byłoby to 43934,505555555555555555555555...).

Wynik ich odjęcia to 0,006944443287037, czyli nieco mniej niż oczekiwane 0,006944444444..., co odpowiada 10 minutom.

Prosimy o wsparcie!