2013-08-19 7 views
12

Welcher ist der effizienteste Weg, um eine Zahl zu runden und dann abzuschneiden (Nachkommastellen nach dem Aufrunden entfernen)?Lua: Runden von Zahlen und dann Abschneiden

Wenn beispielsweise die Dezimalzahl über 0,5 liegt (also 0,6, 0,7 usw.), möchte ich aufrunden und dann abschneiden (Fall 1). Ansonsten würde ich abschneiden möchte (Fall 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) 

Antwort

15

Es gibt keine build-in Math.round() Funktion in Lua, aber Sie können Folgendes tun: print(math.floor(a+0.5)).

3

Sollte math.ceil(a-0.5) korrekt Zahlen halbzahligem zu handhaben

+1

Hängt davon ab was "richtig" bedeutet. Man muss sorgfältig entscheiden, was in etwa halben Schritten zu tun ist und was mit negativen Werten zu tun ist. Beide addieren eine Hälfte und "Boden" und subtrahieren Sie eine Hälfte und "ceil" einführen eine konsistente Neigung zum Fall der genauen Hälfte. Und beide unterscheiden sich von addieren die Hälfte und trunkieren unter der Annahme, dass die Trunkierung in der Regel in Richtung Null rundet. Round to-Value zu implementieren ist in gewissem Sinne "fairer". Die Rundung ist gespickt mit Subtilität. – RBerteig

10

Ein Trick, der für die Rundung auf Dezimalstellen andere als ganze Zahlen zu übergeben Sie den Wert durch formatiert ASCII-Text, und verwenden Sie die %f Format-String zu spezifizieren nützlich ist die gewünschte Rundung. Zum Beispiel

mils = tonumber(string.format("%.3f", exact)) 

den beliebigen Wert in exact auf ein Vielfaches von 0.001 abzurunden.

Ein ähnliches Ergebnis kann mit der Skalierung vor und nach der Verwendung eines von math.floor() oder math.ceil() erzielt werden, aber die Details entsprechend Ihren Erwartungen in Bezug auf die Behandlung von Randfällen zu bekommen, kann schwierig sein. Nicht, dass dies kein Problem mit string.format(), aber eine Menge Arbeit ist in die Herstellung von "erwarteten" Ergebnissen gegangen.

Um auf ein Vielfaches von etwas anderem als einer Zehnerpotenz zu runden, müssen Sie immer noch skalieren und haben immer noch alle schwierigen Kantenfälle. Ein Ansatz, der einfach auszudrücken und hat ein stabiles Verhalten ist

function round(exact, quantum) 
    local quant,frac = math.modf(exact/quantum) 
    return quantum * (quant + (frac > 0.5 and 1 or 0)) 
end 

zu schreiben und optimieren den genauen Zustand auf frac (und möglicherweise das Zeichen des exact) die Rand Fällen bekommen Sie wollten.

6

auch negative Zahlen zu unterstützen, verwenden Sie diese:

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

Für schlechte Runden (Schneiden Sie das Ende aus):

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

Nun, wenn Sie möchten, können Sie dies für eine gute Abrundung erweitern .

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)) 

Erwartete Ergebnisse:

3, 3, 42, 5, 5.

für mich gearbeitet: D

2

Hier ist man rund um eine beliebige Anzahl von Ziffern (0, wenn nicht definiert):

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