class Numerals::FltConversion
Public Class Methods
new(context_or_type, options={})
click to toggle source
Options:
-
:input_rounding (optional, a non-exact
Rounding
or rounding mode) which is used when input is approximate as the assumed rounding mode which would be used so that the result numeral rounds back to the input number. :context can be used to use the numeric context as input rounding. input_rounding is also used to round input …
Calls superclass method
Numerals::ContextConversion::new
# File lib/numerals/conversions/flt.rb, line 16 def initialize(context_or_type, options={}) super end
Public Instance Methods
exact?(value, options={})
click to toggle source
# File lib/numerals/conversions/flt.rb, line 38 def exact?(value, options={}) options[:exact] end
number_of_digits(value, options={})
click to toggle source
# File lib/numerals/conversions/flt.rb, line 29 def number_of_digits(value, options={}) base = options[:base] || 10 if base == @context.radix value.number_of_digits else x.class.context[precision: value.number_of_digits].necessary_digits(base) end end
number_to_numeral(number, mode, rounding)
click to toggle source
mode is either :exact or :approximate
# File lib/numerals/conversions/flt.rb, line 43 def number_to_numeral(number, mode, rounding) if number.special? # @context.special?(number) special_num_to_numeral(number) else if mode == :exact exact_num_to_numeral number, rounding else # mode == :approximate approximate_num_to_numeral(number, rounding) end end end
numeral_to_number(numeral, mode)
click to toggle source
# File lib/numerals/conversions/flt.rb, line 55 def numeral_to_number(numeral, mode) if numeral.special? special_numeral_to_num numeral elsif mode == :fixed fixed_numeral_to_num numeral else # mode == :free free_numeral_to_num numeral end end
order_of_magnitude(value, options={})
click to toggle source
# File lib/numerals/conversions/flt.rb, line 20 def order_of_magnitude(value, options={}) base = options[:base] || 10 # value.num_class.radix if value.class.radix == base value.adjusted_exponent + 1 else value.abs.log(base).floor + 1 end end
read(numeral, exact_input, approximate_simplified)
click to toggle source
# File lib/numerals/conversions/flt.rb, line 96 def read(numeral, exact_input, approximate_simplified) if numeral.special? special_numeral_to_num numeral elsif numeral.approximate? && !exact_input if approximate_simplified # akin to @context.Num(numeral_text, :short) short_numeral_to_num numeral else # akin to @context.Num(numeral_text, :free) free_numeral_to_num numeral end else # akin to @context.Num(numeral_text, :fixed) numeral = numeral.exact if exact_input fixed_numeral_to_num numeral end end
write(number, exact_input, output_rounding)
click to toggle source
# File lib/numerals/conversions/flt.rb, line 65 def write(number, exact_input, output_rounding) output_base = output_rounding.base input_base = @context.radix if number.special? # @context.special?(number) special_num_to_numeral number elsif exact_input if output_base == input_base && output_rounding.free? # akin to number.format(base: output_base, simplified: true) general_num_to_numeral number, output_rounding, false else # akin to number.format(base: output_base, exact: true) exact_num_to_numeral number, output_rounding end else if output_base == input_base && output_rounding.preserving? # akin to number.format(base: output_base) Numeral.from_coefficient_scale( number.sign*number.coefficient, number.integral_exponent, approximate: true, base: output_base ) elsif output_rounding.simplifying? # akin to number.forma(base: output_base, simplify: true) general_num_to_numeral number, output_rounding, false else # akin to number.forma(base: output_base, all_digits: true) general_num_to_numeral number, output_rounding, true end end end
Private Instance Methods
approximate_num_to_numeral(number, rounding)
click to toggle source
# File lib/numerals/conversions/flt.rb, line 133 def approximate_num_to_numeral(number, rounding) all_digits = !rounding.free? general_num_to_numeral(number, rounding, all_digits) end
exact_num_to_numeral(number, rounding)
click to toggle source
# File lib/numerals/conversions/flt.rb, line 124 def exact_num_to_numeral(number, rounding) quotient = number.to_r numeral = Numerals::Numeral.from_quotient(quotient, base: rounding.base) unless rounding.free? numeral = rounding.round(numeral) end numeral end
exact_numeral_to_num(numeral)
click to toggle source
# File lib/numerals/conversions/flt.rb, line 197 def exact_numeral_to_num(numeral) @context.Num Rational(*numeral.to_quotient), :fixed end
fixed_numeral_to_num(numeral)
click to toggle source
# File lib/numerals/conversions/flt.rb, line 174 def fixed_numeral_to_num(numeral) # consider: # return exact_numeral_to_num(numeral) if numeral.exact? if numeral.base == @context.radix unless @context.exact? rounding = Rounding[@context.rounding, precision: @context.precision, base: @context.radix] numeral = rounding.round(numeral) end same_base_numeral_to_num numeral else if numeral.repeating? # numeral.exact? exact_numeral_to_num(numeral) else general_numeral_to_num numeral, :fixed end end end
free_numeral_to_num(numeral)
click to toggle source
# File lib/numerals/conversions/flt.rb, line 201 def free_numeral_to_num(numeral) if numeral.base == @context.radix same_base_numeral_to_num numeral else general_numeral_to_num numeral, :free end end
general_num_to_numeral(x, rounding, all_digits)
click to toggle source
# File lib/numerals/conversions/flt.rb, line 138 def general_num_to_numeral(x, rounding, all_digits) sign, coefficient, exponent = x.split # @context.split(x) precision = x.number_of_digits output_base = rounding.base # here rounding_mode is not the output rounding mode, but the rounding mode used for input rounding_mode = (@input_rounding || rounding).mode formatter = Flt::Support::Formatter.new( @context.radix, @context.etiny, output_base, raise_on_repeat: false ) formatter.format( x, coefficient, exponent, rounding_mode, precision, all_digits ) dec_pos, digits = formatter.digits rep_pos = formatter.repeat normalization = :approximate numeral = Numerals::Numeral[digits, sign: sign, point: dec_pos, rep_pos: formatter.repeat, base: output_base, normalize: normalization] numeral = rounding.round(numeral, round_up: formatter.round_up) numeral end
general_numeral_to_num(numeral, mode)
click to toggle source
# File lib/numerals/conversions/flt.rb, line 213 def general_numeral_to_num(numeral, mode) sign, coefficient, scale = numeral.split reader = Flt::Support::Reader.new(mode: mode) if @input_rounding rounding_mode = @input_rounding.mode else rounding_Mode = @context.rounding end reader.read(@context, rounding_mode, sign, coefficient, scale, numeral.base).tap do # @exact = reader.exact? end end
same_base_numeral_to_num(numeral)
click to toggle source
# File lib/numerals/conversions/flt.rb, line 192 def same_base_numeral_to_num(numeral) sign, coefficient, scale = numeral.split @context.Num sign, coefficient, scale end
short_numeral_to_num(numeral)
click to toggle source
# File lib/numerals/conversions/flt.rb, line 209 def short_numeral_to_num(numeral) general_numeral_to_num numeral, :short end
special_num_to_numeral(x)
click to toggle source
# File lib/numerals/conversions/flt.rb, line 116 def special_num_to_numeral(x) if x.nan? Numeral.nan elsif x.infinite? Numeral.infinity @context.sign(x) end end
special_numeral_to_num(numeral)
click to toggle source
# File lib/numerals/conversions/flt.rb, line 165 def special_numeral_to_num(numeral) case numeral.special when :nan @context.nan when :inf @context.infinity numeral.sign end end