Skip to content

Instantly share code, notes, and snippets.

@clemens
Created July 28, 2008 22:03
Show Gist options
  • Save clemens/2961 to your computer and use it in GitHub Desktop.
Save clemens/2961 to your computer and use it in GitHub Desktop.
def number_to_human_size(number, *args)
return number.nil? ? nil : pluralize(number.to_i, "Byte") if number.to_i < 1024
options = args.extract_options!
options.symbolize_keys!
defaults, human = I18n.translate([:'number.format', :'number.human.format'], :locale => options[:locale]) || [{},{}]
defaults = defaults.merge(human)
unless args.empty?
ActiveSupport::Deprecation.warn('number_to_human_size takes an option hash instead of a separate precision argument.', caller)
precision = args[0] || defaults[:precision]
end
precision ||= (options[:precision] || defaults[:precision])
separator ||= (options[:separator] || defaults[:separator])
delimiter ||= (options[:delimiter] || defaults[:delimiter])
number, unit = number_and_unit_for_human_size(number)
number_with_precision(number, :precision => precision,
:separator => separator, :delimiter => delimiter
).sub(/(\d)(#{Regexp.escape(separator)}[1-9]*)?0+\z/, '\1') + " #{unit}"
rescue
number
end
private
def number_and_unit_for_human_size(number)
units = [ "Bytes", "KB", "MB", "GB", "TB" ].freeze
number = Float(number)
exponent = (Math.log(number)/Math.log(1024)).to_i # calculate logarithm for base 1024
exponent = units.size - 1 if exponent > units.size - 1 # we need this to avoid overflow for the highest unit
number /= 1024**exponent
unit = units[exponent]
[ number, unit ]
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment