Class: Numeric
- Defined in:
- lib/epitools/numwords.rb,
lib/epitools/core_ext/numbers.rb,
lib/epitools/core_ext/truthiness.rb
Overview
>> 1.27.million.billion
=> 1_270_000_000_000_000
>> 12873218731.to_words
=> "twelve billion, eight-hundred and seventy-three million, two-hundred and eighteen thousand, seven-hundred and thirty-one"
Works on numbers up to a googol!
Constant Summary collapse
- NAMES_SMALL =
< 20
[ "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" ]
- NAMES_MEDIUM =
20-90
[ "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" ]
- NAMES_LARGE =
>= 100
[ "thousand", "million", "billion", "trillion", "quadrillion", "quintillion", "sextillion", "septillion", "octillion", "nonillion", "decillion", "undecillion", "duodecillion", "tredecillion", "quattuordecillion", "quindecillion", "sexdecillion", "septendecillion", "octodecillion", "novemdecillion", "vigintillion", "unvigintillion", "duovigintillion", "trevigintillion", "quattuorvigintillion", "quinvigintillion", "sexvigintillion", "septenvigintillion", "octovigintillion", "novemvigintillion", "trigintillion", "untrigintillion", "duotrigintillion" ]
- BYTE_SIZE_TABLE =
{ # power # of 1024 # units 0 => "", 1 => "KB", 2 => "MB", 3 => "GB", 4 => "TB", 5 => "PB", 6 => "EB", 7 => "ZB", 8 => "YB", }
Instance Method Summary collapse
- #ago ⇒ Object
-
#choose(r) ⇒ Object
(also: #combinations)
Combinations: compute “n choose r” (self.choose®).
-
#clamp(range) ⇒ Object
Clamp the number to a specific range.
-
#commatize(char = ",") ⇒ Object
Convert this number to a string, adding commas between each group of 3 digits.
- #from_now ⇒ Object
- #human_bytes(decimals = 0) ⇒ Object (also: #human_size)
- #ln ⇒ Object
- #log(n = nil) ⇒ Object
-
#mulmod(n) ⇒ Object
Multiply self by n, returning the integer product and the floating point remainder.
- #number? ⇒ Boolean
-
#perms(r) ⇒ Object
(also: #permutations)
Permutations: compute “n P r”.
-
#things(&block) ⇒ Object
If ‘n.times` is like `each`, `n.things` is like `map`.
- #to_celcius ⇒ Object
- #to_farenheit ⇒ Object
-
#to_hms ⇒ Object
Convert seconds to hours:minutes:seconds (hours is dropped if it’s zero).
- #to_hms_in_words ⇒ Object
- #to_kg ⇒ Object
- #to_lbs ⇒ Object
-
#to_words ⇒ Object
Convert this number to words (eg: 69 => ‘sixty-nine’).
- #truthy? ⇒ Boolean
-
#underscorize ⇒ Object
Convert this number to a string, adding underscores between each group of 3 digits.
Instance Method Details
#ago ⇒ Object
68 69 70 |
# File 'lib/epitools/core_ext/numbers.rb', line 68 def ago Time.now - self end |
#choose(r) ⇒ Object Also known as: combinations
Combinations: compute “n choose r” (self.choose®)
This represents number of ways to pick “r” items from a collection of “self” items (where the order of the items doesn’t matter, and items can’t be repeated.)
eg: 49.choose(6) is how many ways can we pick 6 lottery numbers from a set of 49.
Formula: n! / (r! * (n-r)!) == n * n-1 * … * n-r / r * r-1 * … * 2
136 137 138 |
# File 'lib/epitools/core_ext/numbers.rb', line 136 def choose(r) (self-r+1..self).reduce(:*) / (2..r).reduce(:*) end |
#clamp(range) ⇒ Object
Clamp the number to a specific range
Examples:
234234234523.clamp(0..100) #=> 100
12.clamp(0..100) #=> 12
-38817112.clamp(0..100) #=> 0
36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/epitools/core_ext/numbers.rb', line 36 def clamp(range) if self < range.first range.first elsif self >= range.last if range.exclude_end? range.last - 1 else range.last end else self end end |
#commatize(char = ",") ⇒ Object
Convert this number to a string, adding commas between each group of 3 digits.
(The “char” argument is optional, and specifies what character to use in between
each group of numbers.)
12 13 14 15 16 17 18 19 |
# File 'lib/epitools/core_ext/numbers.rb', line 12 def commatize(char=",") str = self.is_a?(BigDecimal) ? to_s("F") : to_s int, frac = str.split(".") int = int.gsub /(\d)(?=\d{3}+(?:\.|$))(\d{3}\..*)?/, "\\1#{char}\\2" frac ? "#{int}.#{frac}" : int end |
#from_now ⇒ Object
72 73 74 |
# File 'lib/epitools/core_ext/numbers.rb', line 72 def from_now Time.now + self end |
#human_bytes(decimals = 0) ⇒ Object Also known as: human_size
203 204 205 206 207 208 |
# File 'lib/epitools/core_ext/numbers.rb', line 203 def human_bytes(decimals=0) power = self.log(1024).floor base = 1024.0 ** power units = BYTE_SIZE_TABLE[power] "#{(self / base).round(decimals)}#{units}" end |
#ln ⇒ Object
121 122 123 |
# File 'lib/epitools/core_ext/numbers.rb', line 121 def ln Math.log(self) end |
#log(n = nil) ⇒ Object
169 170 171 172 173 174 175 |
# File 'lib/epitools/core_ext/numbers.rb', line 169 def log(n=nil) if n Math.log(self) / Math.log(n) else Math.log(self) end end |
#mulmod(n) ⇒ Object
Multiply self by n, returning the integer product and the floating point remainder.
159 160 161 162 163 164 |
# File 'lib/epitools/core_ext/numbers.rb', line 159 def mulmod(n) prod = self * n intprod = prod.to_i [intprod, prod % intprod] end |
#number? ⇒ Boolean
51 |
# File 'lib/epitools/core_ext/truthiness.rb', line 51 def number?; true; end |
#perms(r) ⇒ Object Also known as: permutations
Permutations: compute “n P r”
This represents number of ways to pick “r” items from a collection of “self” items (where the order of the items DOES matter, and items can’t be repeated.)
eg: 23.perm(3) is how many ways 23 people can win 1st, 2nd and 3rd place in a race.
Formula: n! / (n - r)!
151 152 153 |
# File 'lib/epitools/core_ext/numbers.rb', line 151 def perms(r) (self-r+1..self).reduce(:*) end |
#things(&block) ⇒ Object
If ‘n.times` is like `each`, `n.things` is like `map`. Return
79 80 81 82 83 84 85 |
# File 'lib/epitools/core_ext/numbers.rb', line 79 def things(&block) if block_given? Array.new(self, &block) else (0...self).to_a end end |
#to_celcius ⇒ Object
252 253 254 |
# File 'lib/epitools/core_ext/numbers.rb', line 252 def to_celcius (self - 32) * 5.0 / 9.0 end |
#to_farenheit ⇒ Object
248 249 250 |
# File 'lib/epitools/core_ext/numbers.rb', line 248 def to_farenheit (self * 9.0 / 5.0) + 32 end |
#to_hms ⇒ Object
Convert seconds to hours:minutes:seconds (hours is dropped if it’s zero)
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/epitools/core_ext/numbers.rb', line 215 def to_hms seconds = self days, seconds = seconds.divmod(86400) hours, seconds = seconds.divmod(3600) minutes, seconds = seconds.divmod(60) seconds, frac = seconds.divmod(1) result = "%0.2d:%0.2d" % [minutes,seconds] result = ("%0.2d:" % hours) + result if hours > 0 or days > 0 result = ("%0.2d:" % days) + result if days > 0 result += ("." + frac.round(2).to_s.split(".").last) if frac > 0 result end |
#to_hms_in_words ⇒ Object
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
# File 'lib/epitools/core_ext/numbers.rb', line 231 def to_hms_in_words seconds = self days, seconds = seconds.divmod(86400) hours, seconds = seconds.divmod(3600) minutes, seconds = seconds.divmod(60) seconds, frac = seconds.divmod(1) result = "#{seconds} sec" result = "#{minutes} min, " + result if minutes > 0 result = "#{"hour".amount(hours)}, " + result if hours > 0 or days > 0 result = "#{"day".amount(days)}, " + result if days > 0 # result += ("." + frac.round(2).to_s.split(".").last) if frac > 0 result end |
#to_kg ⇒ Object
260 261 262 |
# File 'lib/epitools/core_ext/numbers.rb', line 260 def to_kg self * 0.45359237 end |
#to_lbs ⇒ Object
256 257 258 |
# File 'lib/epitools/core_ext/numbers.rb', line 256 def to_lbs self / 0.45359237 end |
#to_words ⇒ Object
Convert this number to words (eg: 69 => ‘sixty-nine’). Works with numbers up to a googol (10^100).
39 40 41 42 43 44 45 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 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/epitools/numwords.rb', line 39 def to_words if is_a? Integer num = self else num = self.to_i end if (n = num.to_s.size) > 102 return "more than a googol! (#{n} digits)" end whole_thing = [] triplets = num.commatize.split(',') num_triplets = triplets.size triplets.each_with_index do |triplet, i| next if triplet.to_i == 0 result = [] tens, hunds = nil, nil digits = triplet.chars.to_a raise "Error: Not a triplet: #{triplet}" if digits.size > 3 or digits.size < 1 if digits.size == 3 digit = digits.shift.to_i hunds = NAMES_SMALL[digit] + "-hundred" if digit > 0 digits.shift if digits.first == '0' end if digits.size == 2 n = digits.join('').to_i if n > 0 and n < 20 tens = NAMES_SMALL[n] elsif n > 0 tens = NAMES_MEDIUM[digits.shift.to_i - 2] if digits.first != '0' tens += "-" + NAMES_SMALL[digits.shift.to_i] else digits.shift end end end if digits.size == 1 n = digits.join('').to_i tens = NAMES_SMALL[n] if n > 0 end if hunds if tens result << "#{hunds} and #{tens}" else result << hunds end else result << tens if tens end magnitude = (num_triplets - i) result << NAMES_LARGE[magnitude-2] if magnitude > 1 whole_thing << result.join(' ') if result.any? end whole_thing.join ', ' end |
#truthy? ⇒ Boolean
49 |
# File 'lib/epitools/core_ext/truthiness.rb', line 49 def truthy?; self > 0; end |
#underscorize ⇒ Object
Convert this number to a string, adding underscores between each group of 3 digits.
24 25 26 |
# File 'lib/epitools/core_ext/numbers.rb', line 24 def underscorize commatize("_") end |