Skip to content

Instantly share code, notes, and snippets.

@JeffreyATW
Last active December 20, 2015 17:09
Show Gist options
  • Save JeffreyATW/6166210 to your computer and use it in GitHub Desktop.
Save JeffreyATW/6166210 to your computer and use it in GitHub Desktop.
This code was fun to write, but there's got to be an easier way to do this... right?
def friendly_count(num)
if num >= 1000000000000
'999B+'
elsif num >= 2000000000
"#{num / 1000000000}B"
elsif num >= 1100000000
"#{(num.to_f / 1000000000.0).round(1)}B"
elsif num >= 1000000000
'1B'
elsif num >= 2000000
"#{num / 1000000}M"
elsif num >= 1100000
"#{(num.to_f / 1000000.0).round(1)}M"
elsif num >= 1000000
'1M'
elsif num >= 2000
"#{num / 1000}K"
elsif num >= 1100
"#{(num.to_f / 1000.0).round(1)}K"
elsif num >= 1000
'1K'
else
num
end
end
@danhealy
Copy link

danhealy commented Aug 6, 2013

Well, first off, you can use "_" as a visual separator in long numbers: 1_000_000

Secondly, to get a float result from division only the denominator needs to be a float, so you can get rid of the .to_f in num.to_f

def friendly_count(num)
  len = (num.to_s.length - 1)
  factor = len - (len % 3)
  sig = "%g" % BigDecimal.new((num / 10**(factor).to_f), 2)

  case factor
  when 0
    unit = nil
  when 3
    unit = "K"
  when 6
    unit = "M"
  when 9
    unit = "B"
  else
    sig  = "999"
    unit = "B+"
  end
  puts "#{sig}#{unit}"
end

Guard code omitted. But if you're using Rails, you can just use this view helper:

ApplicationController.helpers.number_to_human(num, :precision => 3, :units => {:thousand => "K", :million => "M", :billion => "B", :trillion => "T"})

It doesn't quite match your result, because it will show 1.02 K for 1024 and it will go past 999B, but it's pretty close.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment