2008-11-08 15 views
54

Comment, en C#, arrondir une valeur quelconque à 10 intervalles? Par exemple, si j'ai 11, je veux qu'il revienne 10, si j'ai 136, alors je veux qu'il revienne 140.Built in. Algorithme .Net pour arrondir la valeur à l'intervalle 10 le plus proche

Je peux facilement le faire à la main

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

Mais je suis à la recherche pour un algorithme intégré pour faire ce travail, quelque chose comme Math.Round(). La raison pour laquelle je ne veux pas le faire à la main est que je ne veux pas écrire un morceau de code identique ou similaire dans mes projets, même pour quelque chose d'aussi simple que ce qui précède.

+4

Si cela fonctionne, pourquoi avez-vous besoin d'autre chose? Juste envelopper dans une méthode d'extension ou une bibliothèque commune et exécuter avec elle –

+1

((nombre + 5)/10) * 10 - bonne raison de trouver un intégré. :-) –

+1

J'ai remarqué qu'il y avait une confusion avec cette question, et vous devriez probablement éditer le titre ou la publication pour le rendre plus clair. En particulier, voulez-vous toujours arrondir, ou arrondir au 10 le plus proche? –

Répondre

81

Il n'y a pas de fonction intégrée dans la bibliothèque de classes qui le fera. Le plus proche est System.Math.Round() qui est seulement pour arrondir les nombres de types Decimal et Double à la valeur entière la plus proche. Toutefois, vous pouvez envelopper votre instruction dans une méthode d'extension, si vous travaillez avec .NET 3.5, ce qui vous permettra d'utiliser la fonction beaucoup plus proprement.

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 vous programmez contre une ancienne version du framework .NET, il suffit de supprimer le « ce » de la fonction roundoff et appeler la fonction comme ceci:

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

Il y a un tas de problèmes avec ce code, à savoir il ne compile pas (type de retour manquant) et il ne tourne pas à le plus proche. Dans votre exemple, il renvoie 230 et 10. –

+0

Fixe, essayez-le maintenant. –

+0

Il ne retournera pas 240, car vous arrondissez vers le bas. –

3

L'arrondi d'un flottant à un entier est similaire à (int) (x + 0.5), par opposition à simplement lancer x - si vous voulez un multiple de 10, vous pouvez facilement l'adapter.

Si vous voulez juste faire des nombres entiers et que vous l'arrondissez à dix, essayez (x + 10/2)/10 * 10.

Modifier: J'ai remarqué que cette réponse ne correspond pas à la demande de l'auteur de l'original, et c'est aussi une forme biaisée d'arrondi que je préfère ne pas faire. Cependant, une autre réponse acceptée a déjà indiqué Math.round(), une solution bien meilleure.

+0

Je dois dire que, même si c'est le truc que j'ai utilisé dans le passé, Math.Round a l'air beaucoup plus propre. –

14

Utilisez Math.Ceiling pour toujours arrondir.

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

Modulus (%) obtient le reste, vous obtenez:

// number = 236 + 10 - 6 

Mettre cela en une méthode d'extension

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(); 

ci-dessus sous la direction: Je suis allé avec mon premier instinct pour utiliser Math.Ceiling

I blogged about this when calculating UPC check digits.

+0

Essayez-le avec 240. Qu'est-ce que vous obtenez alors? Ou d'ailleurs, 11. –

+0

pour les archives: édité ce post @ 7:30 le même jour – Armstrongest

6

Cela pourrait être un peu trop tard, mais je suppose que cela pourrait être une bonne aide un jour ...

J'ai essayé:

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

Pour utiliser:

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

De cette façon, vous avez la possibilité que si la moitié de l'intervalle sera arrondi vers le haut ou vers le bas arrondi.=)

1

Je préfère ne pas apporter la bibliothèque Math ni aller en virgule flottante donc ma suggestion est juste de faire de l'arithmétique entière comme ci-dessous où je arrondis au 1K suivant. Enveloppez-le dans une méthode ou un extrait lambda ou quelque chose si vous ne voulez pas répéter.

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

Je n'ai pas couru des tests de performance sur ce rapport à d'autres moyens, mais je parie que c'est le meilleur moyen de faire économiser peut-être une version déplacement et la rotation de bits de cela.

1

Ancienne question mais voici une façon de faire ce qui a été demandé plus je l'ai étendu pour pouvoir arrondir n'importe quel nombre au nombre de sig figs que vous voulez.

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"); 
    }