2009-09-14 43 views
9

No estoy viendo el resultado que espero con Math.Round.Redondeo a par en C#

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

Según entiendo MidpointRounding.ToEven, el 5 en la posición milésimas debe causar que la salida sea 99.96. ¿No es este el caso?

Incluso he intentado esto, pero volvieron 99,97 así:

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

¿Cuál falto

Gracias!

+4

¿Entonces lo que dices es que quieres _round_ a un número que está _más lejos_? Esa es una extraña definición de "redondeado". –

+1

Eso es redondeo bancario para usted. No es de extrañar que estemos en este lío ;-) –

+4

No, eso no es un redondeo bancario. El redondeo bancario es cuando eliges redondear a par * cuando las dos opciones son igualmente distantes *. No estás en una situación donde las dos opciones son igualmente distantes. Uno de ellos está más cerca que el otro, y usted quiere elegir el que está más lejos. –

Respuesta

24

No está realmente en el punto medio. MidpointRounding.ToEven indica que si tuviera el número 99.965, es decir, 99.96500000 [etc.], , entonces, obtendría 99.96. Como el número que pasas a Math.Round está por encima de este punto medio, está redondeando.

Si desea que su número a redondear al 99,96, haga lo siguiente:

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

Y bueno, aquí hay un poco de práctica función de hacer lo anterior para los casos generales:

// 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
única

Se las vueltas a 99,96 si se encuentra en el punto medio en sí, es decir, 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 para usar IronPython. Me hizo sonreir. –

+0

@Vinay, lo siento por mi edición. Estaba equivocado. –

0

el redondeo punto medio es lo solo si el valor está entre tus dos casos.

En su caso, no es "5", es "535 ...", por lo que es mayor que el punto medio, y las rutinas a .96. Para obtener el comportamiento que esperas, necesitarás truncar hasta el tercer punto decimal, luego redondo usando MidpointRounding.ToEven.

4

El valor MidpointRounding sólo entra en juego cuando se está tratando de redondear un valor cuya dígito menos significativo es exactamente 5. En otras palabras, el valor tendría que ser 99.965 para obtener el resultado deseado. Dado que este no es el caso aquí, simplemente está observando el mecanismo de redondeo estándar. Vea el MSDN page para más información.

3

He aquí los resultados que arrojan algo de luz sobre el tema:

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 

El punto medio es exactamente 5 ... No 535789, no 499999.

0

Rondas Math.round' un valor decimal a una número especificado de dígitos fraccionarios. al redondear 99.96500000,2 rondas a 99.96 y 99.96500001 a 99.67. Redondea el valor completo.

0

Si fuera yo, no usaría Math.Round(), porque eso no es lo que está tratando de lograr.

Esto es lo que haría:

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

que es mucho más fácil de leer y es más de un enfoque matemático.
Multiplico el número por 100, ahora tengo 9996.535789.
Luego péguela, que es distintivamente diferente al redondeo, para devolver el entero más pequeño más cercano al número, para obtener 9996.
Luego divido por 100 para obtener el 99.96 requerido.

P.S.
El piso es lo contrario de techo, que devuelve el número entero más grande más cercano al número.
Por lo tanto, el límite máximo de 9996.535789 es 9997.
Ambas son diferentes de redondeando sin puntos decimales, lo que realmente devuelve el número entero más cercano al número, ya sea más pequeño o más grande, el que esté más cercano; Es por eso que recibía 99.97 cuando usaba redondeo.