Class: Numerals::FloatConversion

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

Instance Attribute Summary

Attributes inherited from ContextConversion

#context, #input_rounding, #type

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ FloatConversion

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



12
13
14
# File 'lib/numerals/conversions/float.rb', line 12

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

Instance Method Details

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

Returns:

  • (Boolean)


34
35
36
# File 'lib/numerals/conversions/float.rb', line 34

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

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



25
26
27
28
29
30
31
32
# File 'lib/numerals/conversions/float.rb', line 25

def number_of_digits(value, options={})
  base = options[:base] || 10
  if base == @context.radix
    @context.precision
  else
    @context.necessary_digits(base)
  end
end

#number_to_numeral(number, mode, rounding) ⇒ Object

mode is either :exact or :approximate



39
40
41
42
43
44
45
46
47
48
49
# File 'lib/numerals/conversions/float.rb', line 39

def number_to_numeral(number, mode, rounding)
  if @context.special?(number)
    special_float_to_numeral(number)
  else
    if mode == :exact
      exact_float_to_numeral number, rounding
    else # mode == :approximate
      approximate_float_to_numeral(number, rounding)
    end
  end
end

#numeral_to_number(numeral, mode) ⇒ Object



51
52
53
54
55
56
57
58
59
# File 'lib/numerals/conversions/float.rb', line 51

def numeral_to_number(numeral, mode)
  if numeral.special?
    special_numeral_to_float numeral
  elsif mode == :fixed
    fixed_numeral_to_float numeral
  else # mode == :free
    free_numeral_to_float numeral
  end
end

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



16
17
18
19
20
21
22
23
# File 'lib/numerals/conversions/float.rb', line 16

def order_of_magnitude(value, options={})
  base = options[:base] || 10 # @contex.radix
  if base == 10
    Math.log10(value.abs).floor + 1
  else
    (Math.log(value.abs)/Math.log(base)).floor + 1
  end
end

#read(numeral, exact_input, approximate_simplified) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/numerals/conversions/float.rb', line 93

def read(numeral, exact_input, approximate_simplified)
  if numeral.special?
    special_numeral_to_float numeral
  # elsif numeral.approximate? && !exact_input
  #   if approximate_simplified
  #     # akin to @context.Num(numeral_text, :short)
  #     short_numeral_to_float numeral
  #   else
  #     # akin to @context.Num(numeral_text, :free)
  #     free_numeral_to_float numeral
  #   end
  else
    # akin to @context.Num(numeral_text, :fixed)
    fixed_numeral_to_float numeral
  end
end

#write(number, exact_input, output_rounding) ⇒ Object



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
# File 'lib/numerals/conversions/float.rb', line 61

def write(number, exact_input, output_rounding)
  output_base = output_rounding.base
  input_base = @context.radix

  if @context.special?(number)
    special_float_to_numeral number
  elsif exact_input
    if output_base == input_base && output_rounding.free?
      # akin to number.format(base: output_base, simplified: true)
      general_float_to_numeral number, output_rounding, false
    else
      # akin to number.format(base: output_base, exact: true)
      exact_float_to_numeral number, output_rounding
    end
  else
    if output_base == input_base && output_rounding.preserving?
      # akin to number.format(base: output_base)
      sign, coefficient, exp = @context.split(number)
      Numerals::Numeral.from_coefficient_scale(
        sign*coefficient, exp,
        approximate: true, base: output_base
      )
    elsif output_rounding.simplifying?
      # akin to number.forma(base: output_base, simplify: true)
      general_float_to_numeral number, output_rounding, false
    else
      # akin to number.forma(base: output_base, all_digits: true)
      general_float_to_numeral number, output_rounding, true
    end
  end
end