Class: Numeric

Inherits:
Object
  • Object
show all
Defined in:
lib/nreadable.rb

Overview

Adds the ability to create various readable representations of numbers to the Numeric Class.

Constant Summary collapse

MAX_NREADABLE_EXP =

Length of symbol arrays - 1.

8
SI_PREFIXES_BIG =

SI-Prefix symbols for positive exponents.

['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']
SI_PREFIXES_SMALL =

SI-Prefix symbols for negative exponents.

['', 'm', 'µ', 'n', 'p', 'f', 'a', 'z', 'y']
BINARY_PREFIXES =

Binary Prefix symbols for positive exponents.

['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi', 'Yi']
NUMBER_NAMING =

English short scale names of numeric values. If you need a different scale or language, just replace the content of this array. Make sure it has MAX_NREADABLE_EXP + 1 fields.

['', 'thousand', 'million', 'billion', 'trillion',
'quadrillion', 'quintillion', 'sextillion', 'septillion']

Instance Method Summary collapse

Instance Method Details

#bin_prefixed(precision = 1) ⇒ String

Creates a representation of the number with a binary prefix attached.

Examples:

1024.bin_prefixed #=> "1Ki"
1_048_576.bin_prefixed + "B" #=> "1MiB" 

Parameters:

  • precision (Integer) (defaults to: 1)

    maximum precision. Must be >= 0.

Returns:

  • (String)

    the formatted number.

Raises:

  • (ArgumentError)
[View source]

116
117
118
119
120
121
122
123
124
# File 'lib/nreadable.rb', line 116

def bin_prefixed( precision = 1 )
  raise ArgumentError, "negative precision" if precision < 0
  return self.to_s if self < 1024 and self > -1024
  return self.to_s if self.is_a? Float and !self.finite?

  number, exponent = base_and_exponent(1024)
  result = nreadable_base_s( number, precision )
  result + BINARY_PREFIXES[exponent]
end

#delimited(delimiter = ',', separator = '.') ⇒ String

Creates a better readable representation of the number by adding thousands separators.

Examples:

12345678.readable #=> "12,345,678"

Parameters:

  • delimiter (String) (defaults to: ',')

    the character(s) to use as the thousands separator.

  • separator (String) (defaults to: '.')

    the character(s) to use as the decimal point.

Returns:

  • (String)

    the number with thousands separator.

[View source]

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/nreadable.rb', line 33

def delimited( delimiter = ',', separator = '.' )
  return self.to_s if self.is_a? Rational
  return self.to_s if self.is_a? Float and !self.finite?

  negative = self < 0
  result   = self.abs.to_s
  length   = result.length
  rounds   = 0
  decimal_position = result.index('.')

  pointer = if decimal_position
    result[decimal_position] = separator
    decimal_position - length - 4
  else
    -4
  end

  while pointer.abs <= length + rounds
    result.insert(pointer, delimiter)
    pointer -= 4
    rounds  += 1
  end

  result = "-" + result if negative
  result
end

#named(precision = 1) ⇒ String

Creates a representation of the number using the short scale large-number naming system with english words. You can change this by modifying the NUMBER_NAMING constant.

Examples:

2000.named #=> "2 thousand"
2_310_000.named #=> "2.3 million"

Parameters:

  • precision (Integer) (defaults to: 1)

    maximum precision. Must be >= 0.

Returns:

  • (String)

    the formatted number.

Raises:

  • (ArgumentError)
[View source]

136
137
138
139
140
141
142
143
144
# File 'lib/nreadable.rb', line 136

def named( precision = 1 )
  raise ArgumentError, "negative precision" if precision < 0
  return self.to_s if self < 1000 and self > -1000
  return self.to_s if self.is_a? Float and !self.finite?

  number, exponent = base_and_exponent(1000)
  result = nreadable_base_s( number, precision )
  "#{result} #{NUMBER_NAMING[exponent]}"
end

#scientific(precision = 6) ⇒ String

Creates a scientific representation of the number. An exponential notation is used if the number is >= 1000 or < 0.01.

Examples:

12.55.scientific #=> "12.55"
10000.scientific #=> "1e+04"
12345.scientific #=> "1.2345e+04"

Parameters:

  • precision (Integer) (defaults to: 6)

    the maximum precision. Only applies if the exponential notation is used. Must be >= 0.

Returns:

  • (String)

    the formatted number.

Raises:

  • (ArgumentError)
[View source]

71
72
73
74
75
76
77
78
79
80
81
# File 'lib/nreadable.rb', line 71

def scientific( precision = 6 )
  raise ArgumentError, "negative precision" if precision < 0
  return self.to_s if (self < 1000 and self >= 0.01) or (self == 0) or
      (self > -1000 and self <= -0.01)
  return self.to_s if self.is_a? Float and !self.finite?

  result = sprintf("%.#{ precision }e", self)
  position = result.index('e') - 1
  
  strip_insignificant_digits( result, position )
end

#si_prefixed(precision = 6) ⇒ String

Creates a representation of the number with a SI prefix attached.

Examples:

0.0000012.si_prefixed #=> "1.2µ"
1000.si_prefixed #=> "1k"

Parameters:

  • precision (Integer) (defaults to: 6)

    maximum precision. Must be >= 0.

Returns:

  • (String)

    the formatted number.

Raises:

  • (ArgumentError)
[View source]

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/nreadable.rb', line 91

def si_prefixed( precision = 6 )
  raise ArgumentError, "negative precision" if precision < 0
  return self.to_s if (self < 1000 and self >= 1) or (self == 0) or
      (self > -1000 and self <= -1)
  return self.to_s if self.is_a? Float and !self.finite?

  number, exponent = base_and_exponent(1000)
  unit = if exponent >= 0
    SI_PREFIXES_BIG[exponent]
  else
    SI_PREFIXES_SMALL[exponent.abs]
  end

  result = nreadable_base_s( number, precision )
  result + unit
end