2013-08-19 20 views
12

Qual è il modo migliore per arrotondare un numero e poi troncarlo (rimuovere i numeri decimali dopo l'arrotondamento)?Lua: arrotondare i numeri e quindi troncare

ad esempio se il decimale è superiore a 0,5 (ovvero, 0,6, 0,7 e così via), voglio arrotondare e quindi troncare (caso 1). In caso contrario, vorrei troncare (caso 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) 

risposta

15

non esiste alcuna funzione build-in Math.round() in Lua, ma è possibile effettuare le seguenti operazioni: print(math.floor(a+0.5)).

3

Dovrebbe essere math.ceil(a-0.5) di gestire correttamente i numeri semi-intero

+1

Dipende da cosa significa "correttamente". Bisogna decidere con cura cosa fare a mezzo passo e cosa fare con i valori negativi. Entrambi aggiungono metà e 'piano' e sottraggono una metà e' ceil' introducono una deviazione coerente al caso della metà esatta. Ed entrambi sono diversi dall'aggiunta della metà e troncati assumendo che il troncamento di solito giri verso lo zero. Implementare intorno al valore pari è più "giusto" in un certo senso. L'arrotondamento è irto di sottigliezza. – RBerteig

10

Un trucco che è utile per l'arrotondamento in cifre decimali diversi numeri interi è quello di passare il valore attraverso il testo ASCII formattato, e utilizzare la stringa di formato %f per specificare l'arrotondamento desiderato Ad esempio

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

sarà arrotondare il valore arbitrario in exact ad un multiplo di 0.001.

Un risultato simile si può avere con il ridimensionamento prima e dopo l'utilizzo di uno o di math.floor()math.ceil(), ma ottenere i particolari di destra secondo le vostre aspettative che circondano il trattamento di casi limite può essere difficile. Non che questo non sia un problema con string.format(), ma è stato fatto molto lavoro per produrre risultati "previsti".

Arrotondare a un multiplo di qualcosa di diverso da una potenza di dieci richiederà ancora il ridimensionamento, e ha ancora tutti i casi più difficili. Un approccio che è semplice da esprimere e ha un comportamento stabile è quello di scrivere

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

e ottimizzare la condizione esatta su frac (e, eventualmente, il segno della exact) per ottenere i casi limite che volevi.

6

Per sostenere anche i numeri negativi, utilizza questo:

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

Per cattiva arrotondamento (tagliare l'estremità fuori):

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

Beh, se si vuole, è possibile espandere questo per il bene di arrotondamento .

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

Risultati attesi:

3, 3, 42, 5, 5.

ha funzionato per me: D

2

Ecco uno a turno ad un numero arbitrario di cifre (0 se non definito):

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