2013-08-19 28 views
12

Jaki jest najlepszy sposób na zaokrąglenie liczby, a następnie jej obcięcie (usunięcie miejsc dziesiętnych po zaokrągleniu)?Lua: Zaokrąglanie liczb, a następnie obcięcie

na przykład jeśli dziesiętnie jest powyżej 0,5 (to jest 0,6, 0,7 itd.), Chcę zaokrąglić, a następnie skrócić (przypadek 1). W przeciwnym razie, chciałbym skrócić (przypadek 2)

for example: 
232.98266601563 => after rounding and truncate = 233 (case 1) 
232.49445450000 => after rounding and truncate = 232 (case 2) 
232.50000000000 => after rounding and truncate = 232 (case 2) 

Odpowiedz

15

Nie ma wbudowany Math.round function() w Lua, ale można wykonać następujące czynności: print(math.floor(a+0.5)).

3

Powinny być math.ceil(a-0.5) prawidłowo obsługiwać numery pół-całkowitych

+1

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

10

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ś.

6

Aby również wspierać liczb ujemnych, użyj tego:

function round(x) 
    return x>=0 and math.floor(x+0.5) or math.ceil(x-0.5) 
end 
0

za złe zaokrąglenia (cięcie koniec Off):

function round(number) 
     return number - (number % 1) 
    end 

Cóż, jeśli chcesz, możesz to na dobre zaokrąglenia rozwiń .

function round(number) 
     if (number - (number % 0.1)) - (number - (number % 1)) < 0.5 then 
     number = number - (number % 1) 
     else 
     number = (number - (number % 1)) + 1 
     end 
    return number 
    end 

print(round(3.1)) 
print(round(math.pi)) 
print(round(42)) 
print(round(4.5)) 
print(round(4.6)) 

Oczekiwane rezultaty:

3, 3, 42, 5, 5.

pracował dla mnie: D

2

Oto jeden do rundy do dowolnej liczby cyfr (0, jeśli nie zdefiniowany):

function round(x, n) 
    n = math.pow(10, n or 0) 
    x = x * n 
    if x >= 0 then x = math.floor(x + 0.5) else x = math.ceil(x - 0.5) end 
    return x/n 
end