Module: FatCore::Numeric
- Included in:
- Numeric
- Defined in:
- lib/fat_core/numeric.rb
Instance Method Summary collapse
-
#commas(places = nil) ⇒ String
Convert this number into a string and insert grouping commas into the whole number part and round the decimal part to
placesdecimal places, with the default number of places being zero for an integer and 4 for a non-integer. -
#group(places = nil, delim = ',') ⇒ String
Convert this number into a string and insert grouping delimiter character,
deliminto the whole number part and round the decimal part toplacesdecimal places, with the default number of places being zero for an integer and 4 for a non-integer. -
#int_if_whole ⇒ Numeric, Integer
Return an Integer type, but only if the fractional part of self is zero; otherwise just return self.
-
#secs_to_hms ⇒ String
Convert self, regarded as a number of seconds, into a string of the form HH:MM:SS.dd, that is to hours, minutes and seconds and fractions of seconds.
-
#signum ⇒ Integer
Return the signum function for this number, i.e., 1 for a positive number, 0 for zero, and -1 for a negative number.
-
#tex_quote ⇒ Object
Quote self for use in TeX documents.
-
#whole? ⇒ Boolean
Return whether this is a whole number.
Instance Method Details
#commas(places = nil) ⇒ String
Convert this number into a string and insert grouping commas into the
whole number part and round the decimal part to places decimal places,
with the default number of places being zero for an integer and 4 for a
non-integer. The fractional part is padded with zeroes on the right to
come out to places digits after the decimal place.
38 39 40 |
# File 'lib/fat_core/numeric.rb', line 38 def commas(places = nil) group(places, ',') end |
#group(places = nil, delim = ',') ⇒ String
Convert this number into a string and insert grouping delimiter character,
delim into the whole number part and round the decimal part to places
decimal places, with the default number of places being zero for an
integer and 4 for a non-integer. The fractional part is padded with zeroes
on the right to come out to places digits after the decimal place. This
is the same as #commas, but allows the delimiter to be any string.
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 |
# File 'lib/fat_core/numeric.rb', line 59 def group(places = nil, delim = ',') # Return number as a string with embedded commas # for nice printing; round to places places after # the decimal # Only convert to string numbers with exponent unless they are # less than 1 (to ensure that really small numbers round to 0.0) return to_s if abs > 1.0 && to_s.include?('e') # Round if places given str = if places.nil? whole? ? to_i.to_s : to_f.to_s else to_f.round(places).to_s end # Break the number into parts; underscores are possible in all components. str =~ /\A(?<sg>[-+])?(?<wh>[\d_]*)((\.)?(?<fr>[\d_]*))?(?<ex>x[eE][+-]?[\d_]+)?\z/ sig = Regexp.last_match[:sg] || '' whole = Regexp.last_match[:wh] ? Regexp.last_match[:wh].delete('_') : '' frac = Regexp.last_match[:fr] || '' exp = Regexp.last_match[:ex] || '' # Pad out the fractional part with zeroes to the right unless places.nil? n_zeroes = [places - frac.length, 0].max frac += '0' * n_zeroes if n_zeroes.positive? end # Place the commas in the whole part only whole = whole.reverse whole.gsub!(/([0-9]{3})/, "\\1#{delim}") whole.gsub!(/#{Regexp.escape(delim)}$/, '') whole.reverse! if frac.blank? # || places <= 0 sig + whole + exp else sig + whole + '.' + frac + exp end end |
#int_if_whole ⇒ Numeric, Integer
Return an Integer type, but only if the fractional part of self is zero; otherwise just return self.
120 121 122 |
# File 'lib/fat_core/numeric.rb', line 120 def int_if_whole whole? ? floor : self end |
#secs_to_hms ⇒ String
Convert self, regarded as a number of seconds, into a string of the form HH:MM:SS.dd, that is to hours, minutes and seconds and fractions of seconds.
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/fat_core/numeric.rb', line 131 def secs_to_hms frac = self % 1 mins, secs = divmod(60) hrs, mins = mins.divmod(60) if frac.round(5) > 0.0 format( '%02<hrs>d:%02<mins>d:%02<secs>d.%<frac>d', { hrs: hrs, mins: mins, secs: secs, frac: frac.round(5) * 100 }, ) else format( '%02<hrs>d:%02<mins>d:%02<secs>d', { hrs: hrs, mins: mins, secs: secs }, ) end end |
#signum ⇒ Integer
Return the signum function for this number, i.e., 1 for a positive number, 0 for zero, and -1 for a negative number.
17 18 19 20 21 22 23 |
# File 'lib/fat_core/numeric.rb', line 17 def signum raise NotImplementedError unless real? return 1 if positive? return -1 if negative? 0 end |
#tex_quote ⇒ Object
Quote self for use in TeX documents. Since number components are not
special to TeX, this just applies #to_s
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/fat_core/numeric.rb', line 155 def tex_quote case self when Float if self == Float::INFINITY "$\\infty$" elsif self == -Float::INFINITY "$-\\infty$" elsif self == Math::PI "$\\pi$" elsif self == Math::E "$e$" else to_s.tex_quote end when Rational "$\\frac{#{numerator}}{#{denominator}}$" when Complex if imaginary.zero? real.int_if_whole.tex_quote elsif imaginary == 1.0 if real == Math::PI "$\\pi+i$" elsif real == Math::E "$e+i$" else "$#{real.int_if_whole}+i$" end elsif imaginary == Math::PI if real == Math::PI "$\\pi+\\pi i$" elsif real == Math::E "$e+\\pi i$" else "$#{real.int_if_whole}+\\pi i$" end elsif imaginary == Math::E if real == Math::PI "$\\pi+e i$" elsif real == Math::E "$e+e i$" else "$#{real.int_if_whole}+e i$" end else "$#{real.int_if_whole}+#{imaginary.int_if_whole}i$" end else to_s.tex_quote end end |
#whole? ⇒ Boolean
Return whether this is a whole number.
108 109 110 |
# File 'lib/fat_core/numeric.rb', line 108 def whole? floor == self end |