Sztuczka, która jest przydatna do zaokrąglania w cyfr dziesiętnych innych niż całych liczb całkowitych jest przekazanie wartości przez sformatowany tekst ASCII i użyć ciąg formatu %f
określić wymagane zaokrąglenie. Na przykład
mils = tonumber(string.format("%.3f", exact))
będzie zaokrąglić arbitralną wartość exact
wielokrotności 0,001.
Podobny wynik można uzyskać dzięki skalowaniu przed i po użyciu jednego z math.floor()
lub math.ceil()
, ale uzyskanie szczegółów zgodnie z oczekiwaniami dotyczącymi leczenia przypadków brzegowych może być trudne. Nie oznacza to, że nie jest to problemem z string.format()
, ale wiele pracy zostało już wykonane, aby uzyskać "oczekiwane" wyniki.
Zaokrąglanie do wielokrotności czegoś innego niż potęga dziesięciu nadal będzie wymagać skalowania i nadal będzie zawierało wszystkie trudne przypadki. Jednym ze sposobów, który jest prosty do wyrażania i ma stabilne zachowanie jest napisać
function round(exact, quantum)
local quant,frac = math.modf(exact/quantum)
return quantum * (quant + (frac > 0.5 and 1 or 0))
end
i dostosować dokładny stan na frac
(i ewentualnie znakiem exact
), aby uzyskać przypadków brzegowych chciałeś.
Zależy od tego, co "poprawnie" oznacza. Trzeba ostrożnie zdecydować, co zrobić z połową kroków i co zrobić z wartościami ujemnymi. Zarówno dodać połowę i "podłogę", a odjąć połowę, a "ceil" wprowadzić spójne odchylenie do przypadku dokładnej połowy. Oba różnią się od dodawania połowy i obcięcia, zakładając, że skrócenie zazwyczaj kończy się na zero. Realizacja rundy w celu osiągnięcia nawet wartości jest w pewnym sensie bardziej "sprawiedliwa". Zaokrąglanie jest pełne subtelności. – RBerteig