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)


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.



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)


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)


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)


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