2010-10-19 19 views
12

Ho un problema di arrotondamento all'interno di .Net..Net Arrotondamento numero

Sto arrotondando un numero di 3 cifre fino a due cifre e causa alcuni problemi con un numero.

Se tento di arrotondare 34.425 a due cifre decimali, arrotondarlo a 34.43. Sto usando l'opzione roundawayfromzero e ha funzionato per ogni numero nel programma, tranne per questo fino ad ora.

Il codice Math.Round(34.425, 2, MidpointRounding.AwayFromZero) deve essere uguale a 34,43, tuttavia, è uguale a 34,42.

Se provo con un altro numero, funziona correttamente.

Math.Round(34.435, 2, MidpointRounding.AwayFromZero) = 34.44 

Math.Round(34.225, 2, MidpointRounding.AwayFromZero) = 34.23 

Math.Round(34.465, 2, MidpointRounding.AwayFromZero) = 34.47 

Volevo solo verificare se qualcuno ha incontrato questo problema in precedenza?

Per ora ho risolto questo problema convertendo il numero in un decimale. Ho cambiato il codice per questo e funziona bene ora:

Math.Round(CDec(34.425), 2, MidpointRounding.AwayFromZero) = 34.43 

io sono solo alla ricerca di una ragione sul perché il mio vecchio codice non ha funzionato.

Grazie!

Aggiornato il codice al punto AwayFromZero

risposta

20

galleggiante corretta non è mai esatto, 34,425 possono avere un represantation interna 34,4249999999999 .. che sarà arrotondato a 34.42.

Se è necessaria la rappresentazione esatta per i numeri, utilizzare il tipo decimal.

+1

+1 per suggerimento decimale –

+0

Grazie per la risposta. Credo che la mia grande domanda sia: perché funziona per tutti gli altri valori? – Jeff

+0

Anch'io dovrei essere d'accordo con te se fosse una variabile. Tuttavia, stavo mettendo questo valore nella watch list come 34.425. Quindi non dovrebbe essere rappresentato come 34.43499999 ... è corretto nella mia ipotesi? – Jeff

2

Un po 'confuso se si sta effettivamente utilizzando MidpointRounding.ToEven o MidpointRounding.AwayFromZero. Se si utilizza ToEven come indica il primo snippet, questo è il comportamento previsto.

+0

Ho modificato la domanda scusa per la confusione. – Jeff

1

vostre ipotesi ed i risultati sono corretti:

Math.Round(34.225, 2, MidpointRounding.ToEven) == 34.22 
Math.Round(34.465, 2, MidpointRounding.ToEven) == 34.46 

e

Math.Round(34.425, 2, MidpointRounding.ToEven) == 34.42 

Ecco come funziona, ed è quello che ho sulla mia macchina. Arrotondare significa anche solo arrotondare verso l'alto o verso il basso per raggiungere il numero pari successivo al punto decimale di interesse.

+0

Mi dispiace, ho copiato il codice sbagliato. Tutti dovrebbero essere AwayFromZero. – Jeff

+0

Si applica solo se il decimale successivo dopo la virgola decimale è 5 e tutti i decimali successivi sono pari a zero. – phoog

1

Il codice Math.Round (34.425, 2, MidpointRounding.ToEven) deve essere uguale a 34.43, tuttavia, è uguale a 34.42.

Perché? ToEven deve renderlo 34.42 poiché 42 è pari. Il comportamento è corretto.

0

Non uso vb.net, quindi il mio ragionamento potrebbe essere errato, ma basato sui nomi dei parametri MidpointRounding.ToEven, mi aspetterei di 34.425 arrotondare a 34.42; ma mi aspetto anche che il 34.225 venga arrotondato a 34.22 e 34.465 a 34.46. L'arrotondamento dei numeri che terminano in 5 come nei tuoi esempi è una questione di convenzione. La convenzione più comune è intorno a un numero pari, che deduco dal tuo parametro .ToEven.

Inoltre, sospetto che si stia verificando il problema dell'arrotondamento binario/decimale. Il controllo della rappresentazione binaria di 34.425 esce come 10010.011011 ....... Quando si prende in considerazione la memoria del computer e la rappresentazione di un numero decimale (byte, parola, doppia parola, quadrupla e complemento negativo/positivo) ciò può risultare in te non arrotondare il numero che pensavi di essere.

Per ottenere i risultati desiderati, è consigliabile aggiungere 0,00001 a qualsiasi cifra che termina con 5 prima dell'arrotondamento.