Domanda

Non vedo il risultato che mi aspetto con Math.Round.

return Math.Round(99.96535789, 2, MidpointRounding.ToEven); // returning 99.97

Come intendo MidpointRounding.ToEven, il 5 nella posizione millesimale dovrebbe far sì che l'output sia 99.96. Non è così?

Ho anche provato questo, ma ha restituito anche 99,97:

return Math.Round(99.96535789 * 100, MidpointRounding.ToEven)/100;

Cosa mi sto perdendo

Grazie!

È stato utile?

Soluzione

In realtà non sei nel punto medio. MidpointRounding.ToEven indica che se avessi il numero 99.965 , ovvero 99.96500000 [ecc.], quindi otterrai 99,96. Poiché il numero che stai passando a Math.Round è al di sopra di questo punto medio, si sta arrotondando per eccesso.

Se si desidera arrotondare il numero a 99,96, procedere come segue:

// this will round 99.965 down to 99.96
return Math.Round(Math.Truncate(99.96535789*1000)/1000, 2, MidpointRounding.ToEven);

E hey, ecco una piccola funzione utile per fare quanto sopra per i casi generali:

// This is meant to be cute;
// I take no responsibility for floating-point errors.
double TruncateThenRound(double value, int digits, MidpointRounding mode) {
    double multiplier = Math.Pow(10.0, digits + 1);
    double truncated = Math.Truncate(value * multiplier) / multiplier;
    return Math.Round(truncated, digits, mode);
}

Altri suggerimenti

Arrotonda a 99,96 solo se ci si trova sul punto medio stesso, ovvero 99.965:

C:\temp>ipy
IronPython 2.6 Beta 2 (2.6.0.20) on .NET 2.0.50727.4927
Type "help", "copyright", "credits" or "license" for more information.
>>> import clr
>>> from System import Math, MidpointRounding
>>> Math.Round(99.9651, 2, MidpointRounding.ToEven)
99.97
>>> Math.Round(99.965, 2, MidpointRounding.ToEven)
99.96
>>> Math.Round(99.9649, 2, MidpointRounding.ToEven)
99.96
>>> Math.Round(99.975, 2, MidpointRounding.ToEven)
99.98
>>>

Il valore MidpointRounding entra in gioco solo quando si tenta di arrotondare un valore la cui cifra meno significativa è esattamente 5. In altre parole, il valore dovrebbe essere 99.965 per ottenere il risultato desiderato. Dal momento che non è così, stai semplicemente osservando il meccanismo di arrotondamento standard. Vedi la pagina MSDN per maggiori informazioni.

Ecco i risultati che hanno fatto luce sull'argomento:

Math.Round(99.96535789, 2, MidpointRounding.ToEven); // returning 99.97
Math.Round(99.965, 2, MidpointRounding.ToEven);      // returning 99.96
Math.Round(99.96500000, 2, MidpointRounding.ToEven); // returning 99.96

Il punto medio è esattamente 5 ... non 535789, non 499999.

L'arrotondamento del punto medio viene considerato solo se il valore è compreso tra due casi.

Nel tuo caso, non è " 5 " ;, è " 535 ... " ;, quindi è maggiore del punto medio e le routine a .96. Per ottenere il comportamento che ti aspetti, dovrai troncare al terzo punto decimale, POI arrotondato usando MidpointRounding.ToEven.

Math.Round 'Arrotonda un valore decimale a un numero specificato di cifre frazionarie.' quando si arrotondano 99.96500000,2 si arrotondano a 99.96 e 99.96500001 a 99.67. Arrotonda l'intero valore.

Se fossi in me, non userei Math.Round () , perché non è quello che stai cercando di realizzare.

Questo è quello che vorrei fare:

double num = 99.96535789;
double percentage = Math.Floor(100 * num) / 100;  

Che è molto più facile da leggere ed è più un approccio matematico.
Moltiplico il numero per 100 , ora ho 9996.535789 .
Quindi pavimentalo, che è nettamente diverso dall'arrotondamento, per restituire il numero intero più piccolo più vicino al numero, per ottenere 9996 .
Divido quindi per 100 per ottenere il 99,96 richiesto.

P.S.
Floor è l'opposto di soffitto , che restituisce il numero intero più grande più vicino al numero.
Pertanto, il limite di 9996.535789 è 9997 .
Entrambi sono diversi dal arrotondamento senza punti decimali, il che in realtà restituisce il numero intero più vicino al numero, sia esso più piccolo o più grande, a seconda di quale sia il più vicino; ecco perché stavi ottenendo 99,97 quando hai usato arrotondamento .

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