Domanda

Sto cercando di arrotondare un numero al suo primo decimale e, considerando le diverse opzioni MidpointRounding, che sembra funzionare bene. Un problema sorge però quando il numero è sunsequent decimale che aritmeticamente influenzare l'arrotondamento.

Un esempio:

Con 0.1, 0.11..0.19 e 0.141..0.44 funziona:

Math.Round(0.1, 1) == 0.1
Math.Round(0.11, 1) == 0.1
Math.Round(0.14, 1) == 0.1
Math.Round(0.15, 1) == 0.2
Math.Round(0.141, 1) == 0.1

Ma con 0.141..0.149 ritorna sempre 0.1, anche se 0.146..0.149 deve arrotondare a 0.2:

Math.Round(0.145, 1, MidpointRounding.AwayFromZero) == 0.1
Math.Round(0.146, 1, MidpointRounding.AwayFromZero) == 0.1
Math.Round(0.146, 1, MidpointRounding.ToEven) == 0.1
Math.Round(0.146M, 1, MidpointRounding.ToEven) == 0.1M
Math.Round(0.146M, 1, MidpointRounding.AwayFromZero) == 0.1M

Ho cercato di trovare una funzione che risolve questo problema, e funziona bene per questo caso, ma naturalmente viene a mancare glamour se si tenta di arrotondare cioè 0.144449 alla sua prima cifra decimale (che dovrebbe essere 0.2, ma i risultati 0.1.) (Questo non funziona con Math.round () o.)

private double "round"(double value, int digit)
{
    // basically the old "add 0.5, then truncate to integer" trick
    double fix = 0.5D/( Math.Pow(10D, digit+1) )*( value >= 0 ? 1D : -1D );
    double fixedValue = value + fix;

    // 'truncate to integer' - shift left, round, shift right
    return Math.Round(fixedValue * Math.Pow(10D, digit)) / Math.Pow(10D, digit);
}

presumo una soluzione potrebbe essere quella di elencare tutte le cifre, trovare il primo valore maggiore di 4 e poi radunare, altrimenti rotonda verso il basso. Problema 1: Che sembra stupido, Problema 2: Non ho idea di come enumerare le cifre senza un trilione di moltiplicazioni e subtractios

.

Per farla breve:? Qual è il modo migliore per farlo

È stato utile?

Soluzione

Math.Round() si sta comportando in modo corretto.

Al momento di eseguire l'arrotondamento punto medio standard, è mai bisogno di guardare oltre 1 cifra decimale al di là di dove si sta arrotondando al. Se si sono arrotondamento al più vicino decimo, allora non hai mai bisogno di guardare al di là della seconda cifra dopo la virgola.

L'idea con arrotondamento punto centrale è che la metà della a-tra numeri devono arrotondare e mezzo dovrebbero arrotondare. Quindi, per i numeri tra 0,1 e 0,2, la metà di loro deve arrotondare a 0,1 e la metà deve arrotondare a 0,2. Il punto medio tra questi due numeri è 0,15, in modo che è la soglia per arrotondamento. 0.146 è inferiore a 0,15, quindi deve arrotondare a 0,1.

                    Midpoint
0.10                  0.15                  0.20
 |----------------|----|---------------------|
                0.146
       <---- Rounds Down

Altri suggerimenti

Non capisco quello che si sta cercando di realizzare qui. 0,149 arrotondato al primo decimale è 0.1, non 0.2

L'arrotondamento non è un processo iterativo, si arrotonda solo una volta.

0,146 arrotondato a 1 cifra decimale è 0.1.

Non si fa in questo modo:

0.146 --> 0.15
0.15 -->  0.2

È solo fare questo:

0.146 --> 0.1

In caso contrario, il seguente:

0.14444444444444446

sarebbe anche intorno a 0.2, ma non è così, e non dovrebbe.

Non cercare di complicare il 'errori' di arrotondamento. Che è quello che stai cercando di fare.

0,146 dovrebbe rotonda fino a 0,1 se si sta andando a posto un decimale.

Con l'arrotondamento a 0,15 prima, poi di nuovo a 0,2 Sei solo introducendo una maggiore errore di arrotondamento, non di meno.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top