views:

569

answers:

2

I want to round numbers up to their nearest order of magnitude. (I think I said this right)

Here are some examples:

Input => Output

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

Anyone know a quick way to write that in Ruby or Rails?

Essentially I need to know the order of magnitude of the number and how to round by that precision.

Thanks!

A: 

Here is a solution. It implements the following rules:

  • 0 and powers of 10 are not modified;
  • 9??? is rounded up to 10000 (no matter how long);
  • A??? is rounded up to B000 (no matter how long), where B is the digit following 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
pts
You're missing a paren. (And let this be a lesson to you, kids: Don't abuse ternary operators!)
Chuck
Also, roundup(100) = 100 and roundup(6000) = 10000 do not follow the rule of "A??? is rounded up to (A+1)000". It should be 200 and 7000 according to the rules, though I think that the roundup(100) = 100 behavior is probably closer to the function the asker intended.
Chuck
You are correct Chuck. Also, while roundup(100) = 100 is incorrect according to my specs, that would have been cool. I was fine with roundup(100) = 100 or roundup(100) = 200 so I just picked one.
Tony
+5  A: 

Here's another way:

def roundup(num)
  x = Math.log10(num).floor
  num=(num/(10.0**x)).ceil*10**x
  return num
end
BernzSed
you don't need the return statement. Ruby returns the value of the last statement in a method by default. Nice solution though. +1
Demi