Module: BB::Number

Defined in:
lib/blackbox/number.rb

Overview

String utilities.

Constant Summary

STORAGE_UNITS =
%w(byte k M G T P E Z Y).freeze

Class Method Summary (collapse)

Class Method Details

+ (String) to_human_size(number, options = {})

Formats the bytes in number into a more understandable representation (e.g., giving it 1500 yields 1.5k). This method is useful for reporting file sizes to users. This method returns nil if number cannot be converted into a number. You can customize the format in the options hash.

Examples:

to_human_size(123)                                          # => 123
to_human_size(1234)                                         # => 1.2k
to_human_size(12345)                                        # => 12.1k
to_human_size(1234567)                                      # => 1.2M
to_human_size(1234567890)                                   # => 1.1G
to_human_size(1234567890123)                                # => 1.1T
to_human_size(1234567, :precision => 2)                     # => 1.18M
to_human_size(483989, :precision => 0)                      # => 473k
to_human_size(1234567, :precision => 2, :separator => ',')  # => 1,18M

Parameters:

  • number (Fixnum)

    Number value to format.

  • options (Hash) (defaults to: {})

    Options for formatter.

Options Hash (options):

  • :precision (Fixnum) — default: 1

    Sets the level of precision.

  • :separator (String) — default: "."

    Sets the separator between the units.

  • :delimiter (String) — default: ""

    Sets the thousands delimiter.

  • :kilo (String) — default: 1024

    Sets the number of bytes in a kilobyte.

  • :format (String) — default: "%n%u"

    Sets the display format.

Returns:

  • (String)

    The formatted representation of bytes



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/blackbox/number.rb', line 46

def to_human_size(number, args = {})
  begin
     Float(number)
   rescue
     return nil
   end

  options = BB::Hash.symbolize_keys(args)

  precision ||= (options[:precision] || 1)
  separator ||= (options[:separator] || '.')
  delimiter ||= (options[:delimiter] || '')
  kilo      ||= (options[:kilo] || 1024)
  storage_units_format ||= (options[:format] || '%n%u')

  begin
    if number.to_i < kilo
      storage_units_format.gsub(/%n/, number.to_i.to_s).gsub(/%u/, '')
    else
      max_exp  = STORAGE_UNITS.size - 1
      number   = Float(number)
      exponent = (Math.log(number) / Math.log(kilo)).to_i # Convert to base
      exponent = max_exp if exponent > max_exp # we need this to avoid overflow for the highest unit
      number  /= kilo**exponent

      unit = STORAGE_UNITS[exponent]

      escaped_separator = Regexp.escape(separator)
      formatted_number = with_precision(number,
                                        precision: precision,
                                        separator: separator,
                                        delimiter: delimiter).sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '')
      storage_units_format.gsub(/%n/, formatted_number).gsub(/%u/, unit)
    end
  rescue
    number
  end
end

+ (String) with_delimiter(number, options = {})

Formats a number with grouped thousands using delimiter (e.g., 12,324). This method returns nil if number cannot be converted into a number. You can customize the format in the options hash.

Examples:

with_delimiter(12345678)                        # => 12,345,678
with_delimiter(12345678.05)                     # => 12,345,678.05
with_delimiter(12345678, :delimiter => ".")     # => 12.345.678
with_delimiter(12345678, :separator => ",")     # => 12,345,678
with_delimiter(98765432.98, :delimiter => " ", :separator => ",")
# => 98 765 432,98

Parameters:

  • number (Fixnum, Float)

    Number value to format.

  • options (Hash) (defaults to: {})

    Options for formatter.

Options Hash (options):

  • :delimiter (String) — default: ", "

    Sets the thousands delimiter.

  • :separator (String) — default: "."

    Sets the separator between the units.

Returns:

  • (String)

    The formatted representation of the number.



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/blackbox/number.rb', line 160

def with_delimiter(number, args = {})
  begin
     Float(number)
   rescue
     return nil
   end
  options = BB::Hash.symbolize_keys(args)

  delimiter ||= (options[:delimiter] || ',')
  separator ||= (options[:separator] || '.')

  begin
    parts = number.to_s.split('.')
    parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
    parts.join(separator)
  rescue
    number
  end
end

+ (String) with_precision(number, options = {})

Formats a number with the specified level of :precision (e.g., 112.32 has a precision of 2). This method returns nil if number cannot be converted into a number. You can customize the format in the options hash.

Examples:

with_precision(111.2345)                    # => 111.235
with_precision(111.2345, :precision => 2)   # => 111.23
with_precision(13, :precision => 5)         # => 13.00000
with_precision(389.32314, :precision => 0)  # => 389
with_precision(1111.2345, :precision => 2, :separator => ',', :delimiter => '.')
# => 1.111,23

Parameters:

  • number (Fixnum, Float)

    Number value to format.

  • options (Hash) (defaults to: {})

    Options for formatter.

Options Hash (options):

  • :precision (Fixnum) — default: 3

    Sets the level of precision.

  • :separator (String) — default: "."

    Sets the separator between the units.

  • :delimiter (String) — default: ""

    Sets the thousands delimiter.

Returns:

  • (String)

    The formatted representation of the number.



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/blackbox/number.rb', line 112

def with_precision(number, args)
  begin
     Float(number)
   rescue
     return nil
   end

  options = BB::Hash.symbolize_keys(args)

  precision ||= (options[:precision] || 3)
  separator ||= (options[:separator] || '.')
  delimiter ||= (options[:delimiter] || '')

  begin
    rounded_number = (Float(number) * (10**precision)).round.to_f / 10**precision
    with_delimiter("%01.#{precision}f" % rounded_number,
                   separator: separator,
                   delimiter: delimiter)
  rescue
    number
  end
end