numerals 0.0.0 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|