5

For example, if I want 987 to equal "900".

Jesse McCann
  • 55
  • 2
  • 7
  • Welcome to SO. I'd suggest reading stackoverflow.com/help/how-to-ask. It'll help you write solid questions that will yield (hopefully) good answers. And do you want the number to round down and be a string? – orde Jul 20 '17 at 23:53
  • Hello and thank you for the warm welcome! Actually, I would like it to be an number. – Jesse McCann Jul 20 '17 at 23:59

2 Answers2

15
n = 987
m = 2

n.floor(-m)
  #=> 900

See Integer#floor: "When the precision is negative, the returned value is an integer with at least ndigits.abs trailing zeros."

or

(n / 10**m) * 10**m
  #=> 900
Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100
  • Note to myself: this isn't present in ancient ruby versions like 2.2.10 and gives `ArgumentError: wrong number of arguments (1 for 0)`. How can I find out, in which version it was added? – Cadoiz Nov 23 '22 at 15:18
1

You can use logarithms to calculate the best multiple to divide by.

  def round_down(n)
    log = Math::log10(n)
    multip = 10 ** log.to_i
    return (n / multip).to_i * multip 
  end

  [4, 9, 19, 59, 101, 201, 1500, 102000].each { |x|
     rounded = round_down(x)
     puts "#{x} -> #{rounded}"
  }

Result:

4 -> 4
9 -> 9
19 -> 10
59 -> 50
101 -> 100
201 -> 200
1500 -> 1000
102000 -> 100000

This trick is very handy when you need to calculate even tick spacings for graphs.

John C
  • 4,276
  • 2
  • 17
  • 28
  • Depending on how you have the number, one could also consider `n.to_s(10)`, `str.size()-1` or `i.bit_length`. When knowing the decimal digits, you can use `n.floor(-digits-1` as in [Carys answer](https://stackoverflow.com/a/45226958/4575793), which I find more elegant. Another way to say `(n / multip).to_i * multip ` would be `n - (n % multip)`. – Cadoiz Nov 22 '22 at 11:29