Dlaczego jest to skomplikowane
Obiekt Math języka JavaScript dostarcza metodę zaokrąglania do liczb całkowitych. Jeśli chcemy zaokrąglić do określonej liczby miejsc po przecinku, to musimy sobie z tym poradzić sami. Ten post nie zagłębia się w szczegóły arytmetyki zmiennoprzecinkowej, ale w skrócie większość języków programowania używa binarnej reprezentacji zmiennoprzecinkowej, która może jedynie przybliżać wiele ułamków dziesiętnych. Skutkuje to błędami zaokrąglania dla najczęstszych podejść do zaokrąglania w JavaScript.
Błędy zaokrąglania
Najczęstszym rozwiązaniem dla zaokrąglania do miejsca dziesiętnego jest albo użycie Number.prototype.toFixed()
, albo pomnożenie liczby zmiennoprzecinkowej przez jakąś potęgę 10, aby wykorzystać Math.round()
. Oba działają, z wyjątkiem tego, że czasami wartość dziesiętna 5 jest zaokrąglana w dół zamiast w górę.
Number((1.005).toFixed(2)); // 1 instead of 1.01
Math.round(1.005*100)/100; // 1 instead of 1.01
Najlepsze rozwiązanie
Problem zaokrąglania można uniknąć, używając liczb reprezentowanych w notacji wykładniczej:
Number(Math.round(1.005+'e2')+'e-2'); // 1.01
A żeby to wyabstrahować do czegoś bardziej użytecznego:
function round(value, decimals) { return Number(Math.round(value+'e'+decimals)+'e-'+decimals);}round(1.005, 2); // 1.01