2008-11-08 15 views
54

¿Cómo, en C# redondear cualquier intervalo de valor a 10? Por ejemplo, si tengo 11, yo quiero que vuelva 10, si tengo 136, entonces yo quiero que vuelva 140.Construido en algoritmo .Net para redondear el valor al intervalo 10 más cercano

fácilmente me puedo hacerlo a mano

return ((int)(number/10)) * 10; 

pero estoy en busca para un algoritmo incorporado para hacer este trabajo, algo así como Math.Round(). La razón por la que no quiero hacerlo a mano es que no quiero escribir un código similar o similar en todos mis proyectos, incluso para algo tan simple como el anterior.

+4

Si funciona, ¿por qué necesita algo más? Solo envuélvalo en un método de extensión o biblioteca común y ejecútelo –

+1

((número + 5)/10) * 10 - buena razón para encontrar un built-in. :-) –

+1

Noté que hay confusión con esta pregunta y probablemente deba editar el título o la publicación para que quede más claro. En particular, ¿desea redondear siempre, o redondear al 10 más cercano? –

Respuesta

81

No hay una función incorporada en la biblioteca de clases que lo haga. El más cercano es System.Math.Round() que es solo para redondear números de tipos Decimal y Doble al valor entero más cercano. Sin embargo, puede envolver su resumen en un método de extensión, si está trabajando con .NET 3.5, lo que le permitirá utilizar la función de forma mucho más limpia.

public static class ExtensionMethods 
{ 
    public static int RoundOff (this int i) 
    { 
     return ((int)Math.Round(i/10.0)) * 10; 
    } 
} 

int roundedNumber = 236.RoundOff(); // returns 240 
int roundedNumber2 = 11.RoundOff(); // returns 10 

Si está programando en contra de una versión anterior del marco .NET, simplemente retire el "presente" de la función de redondeo, y llamar a la función de este modo:

int roundedNumber = ExtensionMethods.RoundOff(236); // returns 240 
int roundedNumber2 = ExtensionMethods.RoundOff(11); // returns 10 
+0

Hay un montón de problemas con este código, es decir, no se compila (tipo de devolución faltante) y no se redondea a el más cercano. En su ejemplo, devuelve 230 y 10. –

+0

Solucionado, pruébelo ahora. –

+0

Todavía no devolverá 240, porque está redondeando hacia abajo. –

3

Redondear un flotador a un número entero es similar a (int) (x + 0.5), en oposición a simplemente lanzar x - si quiere un múltiplo de 10, puede adaptarlo fácilmente.

Si solo quieres hacer cálculos enteros y lo estás redondeando a diez, prueba (x + 10/2)/10 * 10.

Editar: Me di cuenta de que esta respuesta no cumple con la solicitud del autor del original, y también es una forma de redondeo sesgada que prefiero no hacer. Sin embargo, otra respuesta aceptada ya indicó Math.round(), una solución mucho mejor.

+0

Tengo que decir que, aunque este es el truco que utilicé en pasado, Math.Round parece mucho más limpio. –

14

Use Math.Ceiling para redondear siempre.

int number = 236; 
number = (int)(Math.Ceiling(number/10.0d) * 10); 

módulo (%) obtiene el resto, por lo que se obtiene:

// number = 236 + 10 - 6 

poner esto en un método de extensión

public static int roundupbyten(this int i){ 
    // return i + (10 - i % 10); <-- logic error. Oops! 
    return (int)(Math.Ceiling(i/10.0d)*10); // fixed 
} 

// call like so: 
int number = 236.roundupbyten(); 

anteriormente editado: Debería haber ido con mi primera instinto de utilizar Math.Ceiling

I blogged about this when calculating UPC check digits.

+0

Pruébalo con 240. ¿Qué obtienes entonces? O para el caso, 11. –

+0

para los archivos: editado esta publicación @ 7:30 el mismo día – Armstrongest

6

Esto podría ser una poco demasiado tarde, pero supongo que esto podría ser de buena ayuda algún día ...

he intentado esto:

public int RoundOff(int number, int interval){ 
    int remainder = number % interval; 
    number += (remainder < interval/2) ? -remainder : (interval - remainder); 
    return number; 
} 

Para usar:

int number = 11; 
int roundednumber = RoundOff(number, 10); 

De esta manera, usted tiene la opción ya sea si la mitad del intervalo se redondeará hacia arriba o redondeado hacia abajo.=)

1

Prefiero no entrar en la biblioteca Math ni ir al punto flotante, por lo que mi sugerencia es simplemente hacer cálculos aritméticos enteros, como a continuación, donde redondeo a la siguiente 1K. Envuélvalo en un método o fragmento lambda o algo así si no quiere repetir.

int MyRoundedUp1024Int = ((lSomeInteger + 1023)/1024) * 1024; 

no he ejecutar pruebas de rendimiento en este vs. otras las maneras pero me apuesto a que es la forma más rápida de hacerlo guardar tal vez un desplazamiento y la rotación de la versión bits de este.

1

Pregunta anterior, pero aquí hay una manera de hacer lo que se ha pedido, más lo extendí para poder redondear cualquier número al número de sig que desee.

private double Rounding(double d, int digits) 
    { 
     int neg = 1; 
     if (d < 0) 
     { 
      d = d * (-1); 
      neg = -1; 
     } 

     int n = 0; 
     if (d > 1) 
     { 
      while (d > 1) 
      { 
       d = d/10; 
       n++; 
      } 
      d = Math.Round(d * Math.Pow(10, digits)); 
      d = d * Math.Pow(10, n - digits); 
     } 
     else 
     { 
      while (d < 0.1) 
      { 
       d = d * 10; 
       n++; 
      } 
      d = Math.Round(d * Math.Pow(10, digits)); 
      d = d/Math.Pow(10, n + digits); 
     } 

     return d*neg; 
    } 


    private void testing() 
    { 
     double a = Rounding(1230435.34553,3); 
     double b = Rounding(0.004567023523,4); 
     double c = Rounding(-89032.5325,2); 
     double d = Rounding(-0.123409,4); 
     double e = Rounding(0.503522,1); 
     Console.Write(a.ToString() + "\n" + b.ToString() + "\n" + 
      c.ToString() + "\n" + d.ToString() + "\n" + e.ToString() + "\n"); 
    } 
Cuestiones relacionadas