Class: Numerals::FltConversion

Inherits:
ContextConversion show all
Defined in:
lib/numerals/conversions/flt.rb

Instance Attribute Summary

Attributes inherited from ContextConversion

#context, #input_rounding, #type

Instance Method Summary collapse

Constructor Details

#initialize(context_or_type, options = {}) ⇒ FltConversion

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 …



16
17
18
# File 'lib/numerals/conversions/flt.rb', line 16

def initialize(context_or_type, options={})
  super
end

Instance Method Details

#exact?(value, options = {}) ⇒ Boolean

Returns:

  • (Boolean)


38
39
40
# File 'lib/numerals/conversions/flt.rb', line 38

def exact?(value, options={})
  options[:exact]
end

#number_of_digits(value, options = {}) ⇒ Object



29
30
31
32
33
34
35
36
# 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) ⇒ Object

mode is either :exact or :approximate



43
44
45
46
47
48
49
50
51
52
53
# 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) ⇒ Object



55
56
57
58
59
60
61
62
63
# 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 = {}) ⇒ Object



20
21
22
23
24
25
26
27
# 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) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# 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) ⇒ Object



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
# 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