2009-05-17 12 views
5

Je veux arrondir les nombres jusqu'à leur ordre de grandeur le plus proche. (Je pense que je l'ai dit à droite)Comment arrondir des nombres jusqu'à une précision dynamique dans Ruby On Rails?

Voici quelques exemples:

Input => Output 

8 => 10 
34 => 40 
99 => 100 
120 => 200 
360 => 400 
990 => 1000 
1040 => 2000 
1620 => 2000 
5070 => 6000 
9000 => 10000 

Quelqu'un connait un moyen rapide d'écrire que Ruby ou Rails? Essentiellement, j'ai besoin de connaître l'ordre de grandeur du nombre et comment arrondir avec cette précision.

Merci!

Répondre

13

Voici une autre façon:

def roundup(num) 
    x = Math.log10(num).floor 
    num=(num/(10.0**x)).ceil*10**x 
    return num 
end 

Plus idiomatiques:

def roundup(num) 
    x = Math.log10(num).floor 
    (num/(10.0**x)).ceil * 10**x 
end 
+2

vous n'avez pas besoin de l'instruction return. Ruby renvoie la valeur de la dernière instruction d'une méthode par défaut. Belle solution cependant. +1 – Demi

+1

Pour correspondre à la spécification d'origine où 8 => 10, changez la première ligne en 'x = [Math.log10 (num) .floor, 1] .max' –

+0

Veillez à vérifier que num n'est pas 0 ou négatif depuis alors le logarithme ne sera pas défini. – wyclin

0

Voici une solution. Il implémente les règles suivantes:

  • 0 et les puissances de 10 ne sont pas modifiées;
  • 9 ??? est arrondi à 10000 (peu importe combien de temps);
  • A ??? est arrondi à B000 (quelle que soit sa longueur), où B est le chiffre suivant A.

.

def roundup(n) 
    n = n.to_i 
    s = n.to_s 
    s =~ /\A1?0*\z/ ? n : s =~ /\A\d0*\z/ ? ("1" + "0" * s.size).to_i :  
     (s[0, 1].to_i + 1).to_s + "0" * (s.size - 1)).to_i 
end 

fail if roundup(0) != 0 
fail if roundup(1) != 1 
fail if roundup(8) != 10 
fail if roundup(34) != 40 
fail if roundup(99) != 100 
fail if roundup(100) != 100 
fail if roundup(120) != 200 
fail if roundup(360) != 400 
fail if roundup(990) != 1000 
fail if roundup(1040) != 2000 
fail if roundup(1620) != 2000 
fail if roundup(5070) != 6000 
fail if roundup(6000) != 10000 
fail if roundup(9000) != 10000 
+0

Vous manque un paren. (Et que ce soit une leçon pour vous, les enfants: Ne pas abuser des opérateurs ternaires!) – Chuck

+0

En outre, roundup (100) = 100 et roundup (6000) = 10000 ne suivent pas la règle de "A ??? est arrondi à (A + 1) 000 ". Il devrait être de 200 et 7000 selon les règles, bien que je pense que le comportement roundup (100) = 100 est probablement plus proche de la fonction que le demandeur voulait. – Chuck

+0

Vous avez raison Chuck. En outre, alors que roundup (100) = 100 est incorrect selon mes spécifications, cela aurait été cool. J'allais bien avec roundup (100) = 100 ou roundup (100) = 200 alors je viens de choisir un. – Tony