numerals 0.0.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +149 -5
- data/lib/numerals/conversions/bigdecimal.rb +209 -9
- data/lib/numerals/conversions/context_conversion.rb +40 -0
- data/lib/numerals/conversions/float.rb +106 -71
- data/lib/numerals/conversions/flt.rb +115 -44
- data/lib/numerals/conversions/integer.rb +32 -3
- data/lib/numerals/conversions/rational.rb +27 -3
- data/lib/numerals/conversions.rb +74 -33
- data/lib/numerals/digits.rb +8 -5
- data/lib/numerals/format/base_scaler.rb +160 -0
- data/lib/numerals/format/exp_setter.rb +218 -0
- data/lib/numerals/format/format.rb +257 -0
- data/lib/numerals/format/input.rb +140 -0
- data/lib/numerals/format/mode.rb +157 -0
- data/lib/numerals/format/notation.rb +51 -0
- data/lib/numerals/format/notations/html.rb +53 -0
- data/lib/numerals/format/notations/latex.rb +48 -0
- data/lib/numerals/format/notations/text.rb +141 -0
- data/lib/numerals/format/output.rb +167 -0
- data/lib/numerals/format/symbols.rb +565 -0
- data/lib/numerals/format/text_parts.rb +35 -0
- data/lib/numerals/format.rb +25 -0
- data/lib/numerals/formatting_aspect.rb +36 -0
- data/lib/numerals/numeral.rb +34 -21
- data/lib/numerals/repeat_detector.rb +99 -0
- data/lib/numerals/rounding.rb +340 -181
- data/lib/numerals/version.rb +1 -1
- data/lib/numerals.rb +4 -2
- data/numerals.gemspec +1 -1
- data/test/test_base_scaler.rb +189 -0
- data/test/test_big_conversions.rb +105 -0
- data/test/test_digits_definition.rb +23 -28
- data/test/test_exp_setter.rb +732 -0
- data/test/test_float_conversions.rb +48 -30
- data/test/test_flt_conversions.rb +476 -80
- data/test/test_format.rb +124 -0
- data/test/test_format_input.rb +226 -0
- data/test/test_format_mode.rb +124 -0
- data/test/test_format_output.rb +789 -0
- data/test/test_integer_conversions.rb +22 -22
- data/test/test_numeral.rb +35 -0
- data/test/test_rational_conversions.rb +28 -28
- data/test/test_repeat_detector.rb +72 -0
- data/test/test_rounding.rb +158 -0
- data/test/test_symbols.rb +32 -0
- metadata +38 -5
- data/lib/numerals/formatting/digits_definition.rb +0 -75
data/lib/numerals/conversions.rb
CHANGED
@@ -1,48 +1,89 @@
|
|
1
1
|
module Numerals::Conversions
|
2
2
|
|
3
3
|
class <<self
|
4
|
-
def [](type)
|
4
|
+
def [](type, options = nil)
|
5
5
|
if type.respond_to?(:numerals_conversion)
|
6
|
-
type.numerals_conversion
|
6
|
+
type.numerals_conversion(options || {})
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
10
|
def order_of_magnitude(number, options={})
|
11
|
-
self[number.class].order_of_magnitude(number, options)
|
11
|
+
self[number.class, options[:type_options]].order_of_magnitude(number, options)
|
12
12
|
end
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
14
|
+
def number_of_digits(number, options={})
|
15
|
+
self[number.class, options[:type_options]].number_of_digits(number, options)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Convert Numeral to Number
|
19
|
+
#
|
20
|
+
# read numeral, options={}
|
21
|
+
#
|
22
|
+
# If the input numeral is approximate and the destination type
|
23
|
+
# allows for arbitrary precision, then the destination context
|
24
|
+
# precision will be ignored and the precision of the input will be
|
25
|
+
# preserved. The :simplify option affects this case by generating
|
26
|
+
# only the mininimun number of digits needed.
|
27
|
+
#
|
28
|
+
# The :exact option will prevent this behaviour and always treat
|
29
|
+
# input as exact.
|
30
|
+
#
|
31
|
+
# Valid output options:
|
32
|
+
#
|
33
|
+
# * :type class of the output number
|
34
|
+
# * :context context (in the case of Flt::Num, Float) for the output
|
35
|
+
# * :simplify (for approximate input numeral/arbitrary precision type only)
|
36
|
+
# * :exact treat input numeral as if exact
|
37
|
+
#
|
38
|
+
def read(numeral, options={})
|
39
|
+
selector = options[:context] || options[:type]
|
40
|
+
exact_input = options[:exact]
|
41
|
+
approximate_simplified = options[:simplify]
|
42
|
+
conversions = self[selector, options[:type_options]]
|
43
|
+
conversions.read(numeral, exact_input, approximate_simplified)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Convert Number to Numeral
|
47
|
+
#
|
48
|
+
# write number, options={}
|
49
|
+
#
|
50
|
+
# Valid options:
|
51
|
+
#
|
52
|
+
# * :rounding (a Rounding) (which defines output base as well)
|
53
|
+
# * :exact (exact input indicator)
|
54
|
+
#
|
55
|
+
# Approximate mode:
|
56
|
+
#
|
57
|
+
# If the input is treated as an approximation
|
58
|
+
# (which is the case for types such as Flt::Num, Float,...
|
59
|
+
# unless the :exact option is true) then no 'spurious' digits
|
60
|
+
# will be shown (digits that can take any value and the numeral
|
61
|
+
# still would convert to the original number if rounded to the same precision)
|
62
|
+
#
|
63
|
+
# In approximate mode, if rounding is simplifying? (:short), the shortest representation
|
64
|
+
# which rounds back to the origina number with the same precision is used.
|
65
|
+
# If rounding is :free and the output base is the same as the number
|
66
|
+
# internal radix, the exact precision (trailing zeros) of the number
|
67
|
+
# is represented.
|
68
|
+
#
|
69
|
+
# Exact mode:
|
70
|
+
#
|
71
|
+
# Is used for 'exact' types (such as Integer, Rational) or when the :exact
|
72
|
+
# option is defined to be true.
|
73
|
+
#
|
74
|
+
# The number is treated as an exact value, and converted according to
|
75
|
+
# Rounding. (in this case the :free and :short precision roundings are
|
76
|
+
# equivalent)
|
77
|
+
#
|
78
|
+
def write(number, options = {})
|
79
|
+
output_rounding = Rounding[options[:rounding] || Rounding[]]
|
80
|
+
conversion = self[number.class, options[:type_options]]
|
81
|
+
exact_input = conversion.exact?(number, options)
|
82
|
+
conversion.write(number, exact_input, output_rounding)
|
41
83
|
end
|
42
84
|
|
43
|
-
def
|
44
|
-
|
45
|
-
self[type].numeral_to_number(numeral, mode, *args)
|
85
|
+
def exact?(number, options = {})
|
86
|
+
self[number.class, options[:type_options]].exact?(number, options)
|
46
87
|
end
|
47
88
|
|
48
89
|
private
|
data/lib/numerals/digits.rb
CHANGED
@@ -2,8 +2,8 @@ require 'forwardable'
|
|
2
2
|
|
3
3
|
module Numerals
|
4
4
|
|
5
|
-
# Sequence of digit values
|
6
|
-
# Having this encapsulated here
|
5
|
+
# Sequence of digit values, with an Array-compatible interface.
|
6
|
+
# Having this encapsulated here allows changing the implementation
|
7
7
|
# e.g. to an Integer or packed in a String, ...
|
8
8
|
class Digits
|
9
9
|
def initialize(*args)
|
@@ -32,7 +32,7 @@ module Numerals
|
|
32
32
|
:size, :map, :pop, :push, :shift, :unshift,
|
33
33
|
:empty?, :first, :last, :any?, :all?, :[]=
|
34
34
|
|
35
|
-
# The [] with a Range argument or two arguments (index, length)
|
35
|
+
# The [] operator with a Range argument or two arguments (index, length)
|
36
36
|
# returns a Regular Array.
|
37
37
|
def_delegators :@digits_array, :[], :replace
|
38
38
|
include ModalSupport::StateEquivalent # maybe == with Arrays too?
|
@@ -68,7 +68,7 @@ module Numerals
|
|
68
68
|
|
69
69
|
def zero?
|
70
70
|
# value == 0
|
71
|
-
@
|
71
|
+
!@digits_array || @digits_array.empty? || @digits_array.all?{|d| d==0 }
|
72
72
|
end
|
73
73
|
|
74
74
|
# Deep copy
|
@@ -93,7 +93,10 @@ module Numerals
|
|
93
93
|
def truncate!(n)
|
94
94
|
@digits_array.slice! n..-1
|
95
95
|
end
|
96
|
+
|
97
|
+
def valid?
|
98
|
+
@digits_array.none? { |x| !x.kind_of?(Integer) || x < 0 || x >= @radix }
|
99
|
+
end
|
96
100
|
end
|
97
101
|
|
98
102
|
end
|
99
|
-
|
@@ -0,0 +1,160 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module Numerals
|
4
|
+
|
5
|
+
# This converts the number representation contained in an ExpSetter
|
6
|
+
# scaling the base of the significand.
|
7
|
+
#
|
8
|
+
# This is typically used when the ExpSetter base is 2 to render the number
|
9
|
+
# in C99 '%A' format, i.e., in hexadecimal base. Only the significand is
|
10
|
+
# shown in base 16; the exponent is still a power of two, and represented
|
11
|
+
# in base 10.
|
12
|
+
#
|
13
|
+
# This is a generalization of the %A format where any base which is a
|
14
|
+
# power of the original base can be used for the significand.
|
15
|
+
#
|
16
|
+
# The number exponent is previously adjusted in the ExpSetter and that
|
17
|
+
# doesn't change, only the significand parts are converted from the
|
18
|
+
# original base `base` to the new base `base**base_scale`.
|
19
|
+
#
|
20
|
+
# This will require adjusting the repeating digits position and length,
|
21
|
+
# and adding leading 0s (in the original base) to the signficant
|
22
|
+
# and/or trailing digits may be required.
|
23
|
+
#
|
24
|
+
class Format::BaseScaler
|
25
|
+
|
26
|
+
def initialize(exp_setter, base_scale)
|
27
|
+
@setter = exp_setter
|
28
|
+
@numeral = @setter.numeral
|
29
|
+
@base_scale = base_scale
|
30
|
+
@scaled_base = @setter.base**@base_scale
|
31
|
+
adjust
|
32
|
+
end
|
33
|
+
|
34
|
+
include ModalSupport::BracketConstructor
|
35
|
+
|
36
|
+
attr_reader :base_scale, :scaled_base, :numeral
|
37
|
+
|
38
|
+
extend Forwardable
|
39
|
+
def_delegators :@setter,
|
40
|
+
:exponent_base, :exponent, :special?, :special,
|
41
|
+
:repeating?, :sign
|
42
|
+
|
43
|
+
def base
|
44
|
+
scaled_base
|
45
|
+
end
|
46
|
+
|
47
|
+
def fractional_part
|
48
|
+
ungrouped = @setter.fractional_part + (0...@scaling_trailing_size).map{|i| repeat_digit(i)}
|
49
|
+
grouped_digits ungrouped
|
50
|
+
end
|
51
|
+
|
52
|
+
def fractional_part_size
|
53
|
+
(@setter.fractional_part_size + @scaling_trailing_size)/@base_scale
|
54
|
+
end
|
55
|
+
|
56
|
+
def fractional_insignificant_size
|
57
|
+
if @setter.numeral.approximate?
|
58
|
+
(@setter.fractional_insignificant_size + @scaling_trailing_size)/@base_scale
|
59
|
+
else
|
60
|
+
0
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def integer_part
|
65
|
+
ungrouped = [0]*@scaling_leading_size + @setter.integer_part
|
66
|
+
grouped_digits ungrouped
|
67
|
+
end
|
68
|
+
|
69
|
+
def integer_part_size
|
70
|
+
(@setter.integer_part_size + @scaling_leading_size)/@base_scale
|
71
|
+
end
|
72
|
+
|
73
|
+
def integer_insignificant_size
|
74
|
+
if @setter.numeral.approximate?
|
75
|
+
(@setter.integer_insignificant_size + @scaling_leading_size)/@base_scale
|
76
|
+
else
|
77
|
+
0
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def repeat_size_size
|
82
|
+
@repeat_length/@base_scale
|
83
|
+
end
|
84
|
+
|
85
|
+
def repeat_insignificant_size
|
86
|
+
0
|
87
|
+
end
|
88
|
+
|
89
|
+
def repeat_part
|
90
|
+
ungrouped = (@scaling_trailing_size...@scaling_trailing_size+@repeat_length).map{|i| repeat_digit(i)}
|
91
|
+
grouped_digits ungrouped
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
# Return the `scaled_base` digit corresponding to a group of `base_scale` `exponent_base` digits
|
97
|
+
def scaled_digit(group)
|
98
|
+
unless group.size == @base_scale
|
99
|
+
raise "Invalid digits group size for scaled_digit (is #{group.size}; should be #{@base_scale})"
|
100
|
+
end
|
101
|
+
v = 0
|
102
|
+
group.each do |digit|
|
103
|
+
v *= @setter.base
|
104
|
+
v += digit
|
105
|
+
end
|
106
|
+
v
|
107
|
+
end
|
108
|
+
|
109
|
+
# Convert base `exponent_base` digits to base `scaled_base` digits
|
110
|
+
# the number of digits must be a multiple of base_scale
|
111
|
+
def grouped_digits(digits)
|
112
|
+
unless (digits.size % @base_scale) == 0
|
113
|
+
raise "Invalid number of digits for group_digits (#{digits.size} is not a multiple of #{@base_scale})"
|
114
|
+
end
|
115
|
+
digits.each_slice(@base_scale).map{|group| scaled_digit(group)}
|
116
|
+
end
|
117
|
+
|
118
|
+
# Number of digits (base `exponent_base`) to be added to make the number
|
119
|
+
# of digits a multiple of `base_scale`.
|
120
|
+
def padding_size(digits_size)
|
121
|
+
(@base_scale - digits_size) % @base_scale
|
122
|
+
end
|
123
|
+
|
124
|
+
def adjust
|
125
|
+
return if special?
|
126
|
+
@setter_repeat_part = @setter.repeat_part
|
127
|
+
@setter_repeat_part_size = @setter.repeat_part_size
|
128
|
+
|
129
|
+
@scaling_trailing_size = padding_size(@setter.fractional_part_size)
|
130
|
+
@scaling_leading_size = padding_size(@setter.integer_part_size)
|
131
|
+
|
132
|
+
@repeat_length = @setter.repeat_part_size
|
133
|
+
while (@repeat_length % @base_scale) != 0
|
134
|
+
@repeat_length += @setter.repeat_part_size
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def repeat_digit(i)
|
139
|
+
if @setter_repeat_part_size > 0
|
140
|
+
@setter_repeat_part[i % @setter_repeat_part_size]
|
141
|
+
else
|
142
|
+
0
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# Convert base digits to scaled base digits
|
147
|
+
def self.ugrouped_digits(digits, base, base_scale)
|
148
|
+
digits.flat_map { |d|
|
149
|
+
group = Numeral::Digits[base: base]
|
150
|
+
group.value = d
|
151
|
+
ungrouped = group.digits_array
|
152
|
+
if ungrouped.size < base_scale
|
153
|
+
ungrouped = [0]*(base_scale - ungrouped.size) + ungrouped
|
154
|
+
end
|
155
|
+
ungrouped
|
156
|
+
}
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
@@ -0,0 +1,218 @@
|
|
1
|
+
module Numerals
|
2
|
+
|
3
|
+
# Adjust exponent to be used in a Numeral expression;
|
4
|
+
# break up the numeral into integer, fractional and repeating parts.
|
5
|
+
#
|
6
|
+
# setter = ExpSetter[numeral]
|
7
|
+
# # To use 'fixed' format:
|
8
|
+
# setter.exponent = 0
|
9
|
+
# # To use scientific notation:
|
10
|
+
# setter.integer_part_size = 1
|
11
|
+
# # To adjust scientific notation to engineering mode:
|
12
|
+
# setter.integer_part_size += 1 (while setter.exponent % 3) != 0
|
13
|
+
# # To automatically choose between fixed/scientific format:
|
14
|
+
# setter.exponent = 0 # fixed
|
15
|
+
# if setter.leading_size > 6 || setter.trailing_size > 0
|
16
|
+
# setter.integer_part_size = 1 # scientific
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# # To access the numeric parts for formatting:
|
20
|
+
# setter.sign
|
21
|
+
# setter.integer_part # digits before radix point
|
22
|
+
# setter.fractional_part # digits after radix point, before repetition
|
23
|
+
# setter.repeating_part # repeated digits
|
24
|
+
# setter.base # base for exponent
|
25
|
+
# setter.exponent # exponent
|
26
|
+
#
|
27
|
+
class Format::ExpSetter
|
28
|
+
|
29
|
+
def initialize(numeral, options={})
|
30
|
+
@insignificant_digits = options[:insignificant_digits] || 0
|
31
|
+
@numeral = numeral
|
32
|
+
@integer_part_size = @numeral.point
|
33
|
+
@digits = @numeral.digits
|
34
|
+
@exponent = 0
|
35
|
+
@repeat_size = @numeral.repeating? ? @digits.size - @numeral.repeat : 0
|
36
|
+
adjust
|
37
|
+
end
|
38
|
+
|
39
|
+
attr_reader :numeral
|
40
|
+
|
41
|
+
include ModalSupport::BracketConstructor
|
42
|
+
attr_reader :integer_part_size, :exponent
|
43
|
+
attr_reader :trailing_size, :leading_size
|
44
|
+
|
45
|
+
def base
|
46
|
+
@numeral.base
|
47
|
+
end
|
48
|
+
|
49
|
+
def exponent_base
|
50
|
+
base
|
51
|
+
end
|
52
|
+
|
53
|
+
def special?
|
54
|
+
@numeral.special?
|
55
|
+
end
|
56
|
+
|
57
|
+
def special
|
58
|
+
@numeral.special
|
59
|
+
end
|
60
|
+
|
61
|
+
def repeating?
|
62
|
+
@numeral.repeating?
|
63
|
+
end
|
64
|
+
|
65
|
+
def sign
|
66
|
+
@numeral.sign
|
67
|
+
end
|
68
|
+
|
69
|
+
def exponent=(v)
|
70
|
+
if @exponent != v
|
71
|
+
@integer_part_size -= (v - @exponent)
|
72
|
+
@exponent = v
|
73
|
+
adjust
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def integer_part_size=(v)
|
78
|
+
if @integer_part_size != v
|
79
|
+
@exponent -= (v - @integer_part_size)
|
80
|
+
@integer_part_size = v
|
81
|
+
adjust
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def repeat_part
|
86
|
+
if @numeral.repeating?
|
87
|
+
if @repeat_phase != 0 || @numeral.repeat < 0
|
88
|
+
start = @numeral.repeat + @repeat_phase
|
89
|
+
(start...start+repeat_part_size).map{|i| @numeral.digit_value_at(i)}
|
90
|
+
else
|
91
|
+
@digits[@numeral.repeat..-1]
|
92
|
+
end
|
93
|
+
else
|
94
|
+
[]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def repeat_part_size
|
99
|
+
if @numeral.repeating?
|
100
|
+
@digits.size - @numeral.repeat
|
101
|
+
else
|
102
|
+
0
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def fractional_part
|
107
|
+
leading + @digits[@fractional_start...@fractional_end]
|
108
|
+
end
|
109
|
+
|
110
|
+
def integer_part
|
111
|
+
@digits[@integer_start...@integer_end] + trailing
|
112
|
+
end
|
113
|
+
|
114
|
+
def fractional_part_size
|
115
|
+
@fractional_end - @fractional_start + @leading_size
|
116
|
+
end
|
117
|
+
|
118
|
+
attr_reader :integer_insignificant_size, :fractional_insignificant_size
|
119
|
+
|
120
|
+
def repeat_insignificant_size
|
121
|
+
0
|
122
|
+
end
|
123
|
+
|
124
|
+
private
|
125
|
+
|
126
|
+
def trailing
|
127
|
+
if @trailing_size > 0
|
128
|
+
(@digits.size...@digits.size+@trailing_size).map{|i| @numeral.digit_value_at(i)}
|
129
|
+
else
|
130
|
+
[]
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def leading
|
135
|
+
n = @leading_size
|
136
|
+
if @fractional_end < @fractional_start
|
137
|
+
n += @fractional_end - @fractional_start
|
138
|
+
end
|
139
|
+
if n > 0
|
140
|
+
[0]*n
|
141
|
+
else
|
142
|
+
[]
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def adjust
|
147
|
+
raise "Inconsistet number of insignficant digits" if @numeral.repeating? && @insignificant_digits > 0
|
148
|
+
if special?
|
149
|
+
@leading_size = @trailing_size = 0
|
150
|
+
@integer_start = @integer_end = 0
|
151
|
+
@fractional_start = @fractional_end = 0
|
152
|
+
@repeat_phase = 0
|
153
|
+
@integer_insignificant_size = @fractional_insignificant_size = 0
|
154
|
+
elsif @integer_part_size <= 0
|
155
|
+
@trailing_size = 0
|
156
|
+
# integer_part == []
|
157
|
+
@integer_start = @integer_end = @digits.size
|
158
|
+
@integer_insignificant_size = 0
|
159
|
+
if !@numeral.repeating? || @numeral.repeat >= 0 || @integer_part_size >= @numeral.repeat
|
160
|
+
@leading_size = -@integer_part_size
|
161
|
+
@fractional_start = 0
|
162
|
+
if @numeral.repeat
|
163
|
+
if @numeral.repeat >= 0
|
164
|
+
@fractional_end = @numeral.repeat
|
165
|
+
else
|
166
|
+
@fractional_end = @digits.size
|
167
|
+
end
|
168
|
+
@fractional_insignificant_size = 0
|
169
|
+
else
|
170
|
+
@fractional_end = @digits.size
|
171
|
+
@fractional_insignificant_size = [@insignificant_digits, @digits.size].min
|
172
|
+
end
|
173
|
+
@repeat_phase = 0
|
174
|
+
else
|
175
|
+
@leading_size = @numeral.repeat - @integer_part_size
|
176
|
+
@trailing_size = 0
|
177
|
+
@fractional_start = @fractional_end = @digits.size
|
178
|
+
@fractional_insignificant_size = 0
|
179
|
+
@repeat_phase = 0
|
180
|
+
end
|
181
|
+
elsif @integer_part_size >= @digits.size
|
182
|
+
@trailing_size = @integer_part_size - @digits.size
|
183
|
+
@leading_size = 0
|
184
|
+
@integer_start = 0
|
185
|
+
@integer_end = @digits.size
|
186
|
+
@integer_insignificant_size = @insignificant_digits
|
187
|
+
if @numeral.approximate?
|
188
|
+
@integer_insignificant_size += @trailing_size
|
189
|
+
end
|
190
|
+
@fractional_insignificant_size = 0
|
191
|
+
if @numeral.repeating?
|
192
|
+
@repeat_phase = @trailing_size % repeat_part_size
|
193
|
+
@fractional_start = @fractional_end = @digits.size
|
194
|
+
else
|
195
|
+
@repeat_phase = 0
|
196
|
+
@fractional_start = @fractional_end = @digits.size
|
197
|
+
end
|
198
|
+
else
|
199
|
+
@trailing_size = @leading_size = 0
|
200
|
+
@integer_start = 0
|
201
|
+
@integer_end = @integer_part_size
|
202
|
+
@integer_insignificant_size = [@insignificant_digits - (@digits.size - @integer_part_size), 0].max
|
203
|
+
if @numeral.repeating? && @numeral.repeat < @integer_part_size
|
204
|
+
@repeat_phase = (@integer_end - @numeral.repeat) % repeat_part_size
|
205
|
+
@fractional_start = @fractional_end = @digits.size
|
206
|
+
@fractional_insignificant_size = 0
|
207
|
+
else
|
208
|
+
@repeat_phase = 0
|
209
|
+
@fractional_start = @integer_part_size
|
210
|
+
@fractional_end = @numeral.repeat || @digits.size
|
211
|
+
@fractional_insignificant_size = [@insignificant_digits, @fractional_end - @fractional_start].min
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
end
|
217
|
+
|
218
|
+
end
|