2009-09-14 10 views
9

Je ne vois pas le résultat attendu avec Math.Round.Arrondir à même en C#

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

Si je comprends MidpointRounding.ToEven, 5 dans la position de devrait provoquer la millième sortie soit 99,96. Ce n'est pas le cas?

J'ai même essayé, mais il est revenu 99,97 ainsi:

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

Qu'est-ce que je manque

Merci!

+4

Donc, ce que vous dites, c'est que vous voulez qu'il soit _round_ à un nombre qui est plus loin_? C'est une définition étrange de "arrondi". –

+1

C'est l'arrondissement des banquiers pour vous. Pas étonnant que nous soyons dans ce pétrin ;-) –

+4

Non, ce n'est pas l'arrondissement des banquiers. L'arrondi du banquier est lorsque vous choisissez de arrondir à pair * lorsque les deux choix sont également éloignés *. Vous n'êtes pas dans une situation où les deux choix sont également éloignés. L'un d'eux est plus proche que l'autre, et vous voulez choisir celui qui est le plus éloigné. –

Répondre

24

Vous n'êtes pas réellement à mi-chemin. MidpointRounding.ToEven indique que si vous aviez le numéro 99,965, c'est-à-dire 99,96500000 [etc.], puis vous obtiendriez 99,96. Puisque le nombre que vous passez à Math.Round est au-dessus de ce point médian, c'est arrondi à la hausse.

Si vous voulez que votre numéro à arrondir vers le bas à 99,96, faites ceci:

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

Et hey, voici une petite fonction pratique pour faire ce qui précède pour les cas généraux:

// 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); 
} 
8

Il ne tours à 99,96 si vous êtes sur le point médian lui-même, à savoir 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 
>>> 
+1

+1 pour utiliser IronPython. M'a fait sourire. –

+0

@Vinay, désolé pour mon édition j'avais tort .. –

0

l'arrondi point médian est lo oked à seulement si la valeur est entre vos deux cas.

Dans votre cas, ce n'est pas "5", c'est "535 ...", donc c'est plus grand que le point central, et les routines à 0,96. Pour obtenir le comportement que vous attendiez, vous devez tronquer à la troisième décimale, PUIS arrondir en utilisant MidpointRounding.ToEven.

4

La valeur MidpointRounding ne joue que lorsque vous essayez d'arrondir une valeur dont chiffre est moins significatif exactement 5. En d'autres termes, la valeur devrait être 99.965 pour obtenir le résultat souhaité. Comme ce n'est pas le cas ici, vous observez simplement le mécanisme d'arrondi standard. Voir le MSDN page pour plus d'informations.

3

est ici les résultats qui jettent un peu de lumière sur le sujet:

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 

Le milieu est exactement 5 ... pas 535789, pas 499999.

0

Rounds » Math.Round une valeur décimale à une nombre spécifié de chiffres fractionnaires. en arrondissant 99,96500000,2 arrondit à 99,96 et 99,96500001 à 99,67. Il arrondit la valeur complète.

0

Si c'était moi, je n'utiliserais pas Math.Round(), parce que ce n'est pas ce que vous essayez d'accomplir.

C'est ce que je ferais:

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

Ce qui est beaucoup plus facile à lire et est plus d'une approche mathématique.
Je multiplie le nombre par 100, maintenant j'ai 9996.535789.
Ensuite, placez-le, ce qui est distinctement différent de l'arrondi, pour renvoyer le plus petit entier le plus proche du nombre, pour obtenir 9996.
Je divise ensuite par 100 pour obtenir le 99.96 requis.

P.S.
Étage est l'opposé de plafond, qui renvoie le plus grand entier le plus proche du nombre. Par conséquent, le plafond de 9996.535789 est 9997.
Les deux sont différents de arrondissant à aucun point décimal, ce qui renvoie l'entier le plus proche du nombre, qu'il soit plus petit ou plus grand - selon celui qui est le plus proche; c'est pourquoi vous obteniez 99.97 lorsque vous avez utilisé arrondi.