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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e7931e88c73e54a2d95c47f45d222562dc03a02
|
4
|
+
data.tar.gz: 0179555b287f177e458d854708929838c9619bcc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fbdfea7324a61b2d25888c0553acefac0911e97ed9ddd5e9217064694f1f66fefea0ba968941cead3634e0b9c5a4bfa55e12cfcb16896c42407f057724446580
|
7
|
+
data.tar.gz: ea99d01ee36c91692c926d64f022e08274f89b0a3f4f4eb96f0a4dcaaac1c4340c1c6484d9a1b29f235ae370a2fce903624b1e5656f3297ee1026728cf4d6b87
|
data/README.md
CHANGED
@@ -1,9 +1,146 @@
|
|
1
|
-
|
1
|
+
Numerals
|
2
2
|
========
|
3
3
|
|
4
|
-
|
4
|
+
The Numerals module provides formatted input/output for numeric types.
|
5
5
|
|
6
|
-
|
6
|
+
## Use
|
7
|
+
|
8
|
+
require 'numerals'
|
9
|
+
include Numerals
|
10
|
+
|
11
|
+
The Numeral class is used internally to hold the representation of a numeric
|
12
|
+
quantity as numeral in a positional system. Since repeating figures are
|
13
|
+
supported in Numeral, a Numeral can represent exactly any rational number.
|
14
|
+
|
15
|
+
Numerals can be exact or approximate. Exact numerals don't keep trailing zeros:
|
16
|
+
they don't specify a fixed precision. Repeating numerals are always exact.
|
17
|
+
|
18
|
+
Approximate numerals may have trailing zeros and have a determinate number
|
19
|
+
of significant digits. Approximate numerals cannot held repeating figures,
|
20
|
+
since they have limited precision.
|
21
|
+
|
22
|
+
The Conversions module provides conversions between Numerals and the
|
23
|
+
numeric types Integer, Rational, Float, Flt::Num and BigDecimal.
|
24
|
+
|
25
|
+
The Format class holds formatting settings. It can be constructed
|
26
|
+
with this bracket syntax:
|
27
|
+
|
28
|
+
format = Format[mode: :general, rounding: [precision: 10]]
|
29
|
+
|
30
|
+
Which is a shortcut for:
|
31
|
+
|
32
|
+
format = Format[mode: Format::Mode[:general], rounding: Rounding[precision: 10]]
|
33
|
+
|
34
|
+
And can also be expressed as:
|
35
|
+
|
36
|
+
format = Format[Format::Mode[:general], Rounding[precision: 10]]
|
37
|
+
puts format.rounding.precision # -> 10
|
38
|
+
puts format.rounding.mode # -> half_even
|
39
|
+
|
40
|
+
New formats can be derived from an existing one by overriding some of
|
41
|
+
its properties using the brackets operator on it:
|
42
|
+
|
43
|
+
format2 = format[rounding: :half_down]
|
44
|
+
puts format2.rounding.precision # -> 10
|
45
|
+
puts format2.rounding.mode # -> half_down
|
46
|
+
|
47
|
+
## Output
|
48
|
+
|
49
|
+
Let's see how to use a Format to format a number into text form. By
|
50
|
+
default the shortest possible output (that preserves the value) is produced:
|
51
|
+
|
52
|
+
puts Format[].write(0.1) # -> 0.1
|
53
|
+
|
54
|
+
This is because the default Rounding property of Format is Rounding[:short]
|
55
|
+
(rounding to :short precision), so the above is equivalent to:
|
56
|
+
|
57
|
+
puts Format[:short].write(0.1) # -> 0.1
|
58
|
+
puts Format[rounding: :short].write(0.1) # -> 0.1
|
59
|
+
|
60
|
+
To produce a numeric representation that shows explicitly all the precision
|
61
|
+
of the number, the :free rounding precision can be used:
|
62
|
+
|
63
|
+
puts Format[:free].write(0.1) # -> 0.10000000000000001
|
64
|
+
|
65
|
+
Specific precision can be obtained like this:
|
66
|
+
|
67
|
+
puts Format[precision: 6].write(0.1) # -> 0.100000
|
68
|
+
|
69
|
+
But this won't show digits that are insignificant (when the input number
|
70
|
+
is regarded as an approximation):
|
71
|
+
|
72
|
+
puts Format[precision: 20].write(0.1) # -> 0.10000000000000001
|
73
|
+
puts Format[precision: 20].write(Rational(1,10))# -> 0.10000000000000000000
|
74
|
+
|
75
|
+
Although a Float is considered an approximation by default (since
|
76
|
+
it cannot represent arbitrary precision exactly), we can
|
77
|
+
reinterpret it as an exact quantity with the :exact_input Format option:
|
78
|
+
|
79
|
+
puts Format[:exact_input, precision: 20].write(0.1)# -> 0.10000000000000000555
|
80
|
+
puts Format[:exact_input].write(0.1) # -> 0.1000000000000000055511151231257827021181583404541015625
|
81
|
+
|
82
|
+
Rationals are always 'exact' quantities, and they may require infinite
|
83
|
+
digits to be represented exactly in some output bases. This is handled
|
84
|
+
by repeating numerals, which can be represented as text in two modes:
|
85
|
+
|
86
|
+
puts Format[].write(Rational(1,3)) # -> 0.333...
|
87
|
+
puts Format[symbols: [repeat_delimited: true]].write(Rational(1,3))# -> 0.<3>
|
88
|
+
|
89
|
+
## Input
|
90
|
+
|
91
|
+
The same Format class can be used to read formatted text into numeric values
|
92
|
+
with the Format#read() method.
|
93
|
+
|
94
|
+
puts Format[].read('1.0', type: Float) # -> 1.0
|
95
|
+
|
96
|
+
For Flt types such as Flt::DecNum or Flt::BinNum there are a few options
|
97
|
+
to determine the result, since these types can hold arbitrary precision.
|
98
|
+
|
99
|
+
By default, these types are considered 'approximate'. Thus, the result
|
100
|
+
will be a variable-precision result based on the input. The default
|
101
|
+
Format, which has :short (simplifying) precision will produce a simple
|
102
|
+
result with as few significant digits as possible:
|
103
|
+
|
104
|
+
puts Format[:short].read('1.000', type: Flt::DecNum)# -> 1
|
105
|
+
puts Format[:short].read('0.100', type: Flt::BinNum)# -> 0.1
|
106
|
+
|
107
|
+
To retain the precision of the input text, the :free precision should be
|
108
|
+
used:
|
109
|
+
|
110
|
+
puts Format[:free].read('1.000', type: Flt::DecNum)# -> 1.000
|
111
|
+
puts Format[:free].read('0.100', type: Flt::BinNum)# -> 0.1
|
112
|
+
|
113
|
+
As an alternative, the precision implied by the text input can be ignored
|
114
|
+
and the result adjusted to the precision of the destination context. This
|
115
|
+
is done by regarding the input as 'exact'.
|
116
|
+
|
117
|
+
puts Format[:exact_input].read('1.000', type: Flt::DecNum)# -> 1.000000000000000000000000000
|
118
|
+
puts Format[:exact_input].read('0.100', type: Flt::BinNum)# -> 0.1
|
119
|
+
Flt::DecNum.context.precision = 8
|
120
|
+
puts Format[:exact_input].read('1.000', type: Flt::DecNum)# -> 1.0000000
|
121
|
+
|
122
|
+
If the input specifies repeating digits, then it is automatically regarded
|
123
|
+
exact and rounded according to the destination context:
|
124
|
+
|
125
|
+
puts Format[:exact_input].read('0.333...', type: Flt::DecNum)# -> 0.33333333
|
126
|
+
|
127
|
+
Note that the repeating digits have been automatically detected. This
|
128
|
+
happens because the repeating suffix '...' has ben found (it is defined
|
129
|
+
by the Format::Symbols property of Format). An alternative way of
|
130
|
+
specifying repeating digits is by the repeating delimiters specified
|
131
|
+
in Symbols, which are <> by default:
|
132
|
+
|
133
|
+
puts Format[:exact_input].read('0.<3>', type: Flt::DecNum)# -> 0.33333333
|
134
|
+
|
135
|
+
|
136
|
+
A Format can also be used to read a formatted number into a Numeral:
|
137
|
+
|
138
|
+
puts Format[].read('1.25', type: Numeral) # -> Numeral[1, 2, 5, :sign=>1, :point=>1, :normalize=>:approximate, :base=>10]
|
139
|
+
puts Format[].read('1.<3>', type: Numeral) # -> Numeral[1, 3, :sign=>1, :point=>1, :repeat=>1, :base=>10]
|
140
|
+
|
141
|
+
Other examples:
|
142
|
+
|
143
|
+
puts Format[:free, base: 2].read('0.1', type: Flt::DecNum)# -> 0.5
|
7
144
|
|
8
145
|
Roadmap
|
9
146
|
=======
|
@@ -17,8 +154,15 @@ Done:
|
|
17
154
|
|
18
155
|
* Rounding can be applied to Numerals (with rounding options)
|
19
156
|
|
20
|
-
Pending:
|
21
|
-
|
22
157
|
* Numerals can be written into text form using Formatting options
|
23
158
|
|
24
159
|
* Numerals con be read from text form using Formatting options
|
160
|
+
|
161
|
+
* Handling of 'unsignificant' digits: show them either as special
|
162
|
+
symbol, as zeros or omit them (comfigured in Symbols)
|
163
|
+
|
164
|
+
Pending:
|
165
|
+
|
166
|
+
* Padding aspect of formatting on output
|
167
|
+
|
168
|
+
* Show base indicators on output
|
@@ -1,30 +1,230 @@
|
|
1
1
|
require 'numerals/conversions'
|
2
|
+
require 'bigdecimal'
|
3
|
+
require 'singleton'
|
2
4
|
|
3
|
-
class Numerals::BigDecimalConversion
|
5
|
+
class Numerals::BigDecimalConversion < Numerals::ContextConversion
|
6
|
+
|
7
|
+
# Options:
|
8
|
+
#
|
9
|
+
# * :input_rounding (optional, a non-exact Rounding or rounding mode)
|
10
|
+
# which is used when input is approximate as the assumed rounding
|
11
|
+
# mode which would be used so that the result numeral rounds back
|
12
|
+
# to the input number
|
13
|
+
#
|
14
|
+
def initialize(options = {})
|
15
|
+
super BigDecimal, options
|
16
|
+
end
|
4
17
|
|
5
18
|
def order_of_magnitude(value, options={})
|
6
19
|
base = options[:base] || 10
|
7
20
|
if base == 10
|
8
21
|
value.exponent
|
9
22
|
else
|
10
|
-
|
23
|
+
(Math.log(value.abs)/Math.log(base)).floor + 1
|
11
24
|
end
|
12
25
|
end
|
13
26
|
|
14
|
-
def
|
15
|
-
mode = options[:mode] || :fixed
|
27
|
+
def number_of_digits(value, options={})
|
16
28
|
base = options[:base] || 10
|
17
|
-
|
29
|
+
precision = x.precs.first
|
30
|
+
decimal_digits = x.split[1].size
|
31
|
+
n = decimal_digits # or use precision?
|
32
|
+
if base == 10
|
33
|
+
n
|
34
|
+
else
|
35
|
+
Flt::DecNum.context[precision: n].necessary_digits(base)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def exact?(value, options={})
|
40
|
+
options[:exact]
|
41
|
+
end
|
42
|
+
|
43
|
+
def number_to_numeral(number, mode, rounding)
|
44
|
+
if @context.special?(number)
|
45
|
+
special_num_to_numeral number
|
46
|
+
else
|
47
|
+
if mode == :exact
|
48
|
+
exact_num_to_numeral number, rounding
|
49
|
+
else # mode == :approximate
|
50
|
+
approximate_num_to_numeral(number, rounding)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def numeral_to_number(numeral, mode)
|
56
|
+
if numeral.special?
|
57
|
+
special_numeral_to_num numeral
|
58
|
+
elsif mode == :fixed
|
59
|
+
fixed_numeral_to_num numeral
|
60
|
+
else # mode == :free
|
61
|
+
free_numeral_to_num numeral
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def write(number, exact_input, output_rounding)
|
66
|
+
output_base = output_rounding.base
|
67
|
+
input_base = @context.radix
|
68
|
+
|
69
|
+
if @context.special?(number)
|
70
|
+
special_num_to_numeral number
|
71
|
+
elsif exact_input
|
72
|
+
if output_base == input_base && output_rounding.free?
|
73
|
+
# akin to number.format(base: output_base, simplified: true)
|
74
|
+
if true
|
75
|
+
# ALT.1 just like approximate :short
|
76
|
+
general_num_to_numeral number, output_rounding, false
|
77
|
+
else
|
78
|
+
# ALT.2 just like different bases
|
79
|
+
exact_num_to_numeral number, output_rounding
|
80
|
+
end
|
81
|
+
else
|
82
|
+
# akin to number.format(base: output_base, exact: true)
|
83
|
+
exact_num_to_numeral number, output_rounding
|
84
|
+
end
|
85
|
+
else
|
86
|
+
if output_base == input_base && output_rounding.preserving?
|
87
|
+
# akin to number.format(base: output_base)
|
88
|
+
sign, coefficient, exponent = @context.split(number)
|
89
|
+
Numerals::Numeral.from_coefficient_scale sign*coefficient, exponent, approximate: true
|
90
|
+
elsif output_rounding.simplifying?
|
91
|
+
# akin to number.forma(base: output_base, simplify: true)
|
92
|
+
general_num_to_numeral number, output_rounding, false
|
93
|
+
else
|
94
|
+
# akin to number.forma(base: output_base, all_digits: true)
|
95
|
+
general_num_to_numeral number, output_rounding, true
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def read(numeral, exact_input, approximate_simplified)
|
101
|
+
if numeral.special?
|
102
|
+
special_numeral_to_num numeral
|
103
|
+
elsif numeral.approximate? && !exact_input
|
104
|
+
if approximate_simplified
|
105
|
+
# akin to @context.Num(numeral_text, :short)
|
106
|
+
short_numeral_to_num numeral
|
107
|
+
else
|
108
|
+
# akin to @context.Num(numeral_text, :free)
|
109
|
+
free_numeral_to_num numeral
|
110
|
+
end
|
111
|
+
else
|
112
|
+
# akin to @context.Num(numeral_text, :fixed)
|
113
|
+
fixed_numeral_to_num numeral
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
def special_num_to_numeral(x)
|
120
|
+
if x.nan?
|
121
|
+
Numerals::Numeral.nan
|
122
|
+
elsif x.infinite?
|
123
|
+
Numerals::Numeral.infinity @context.sign(x)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def exact_num_to_numeral(number, rounding)
|
128
|
+
quotient = number.to_r
|
129
|
+
numeral = Numerals::Numeral.from_quotient(quotient, base: rounding.base)
|
130
|
+
unless rounding.free?
|
131
|
+
numeral = rounding.round(numeral)
|
132
|
+
end
|
133
|
+
numeral
|
134
|
+
end
|
18
135
|
|
136
|
+
def approximate_num_to_numeral(number, rounding)
|
137
|
+
all_digits = !rounding.free?
|
138
|
+
general_num_to_numeral(number, rounding, all_digits)
|
19
139
|
end
|
20
140
|
|
21
|
-
def
|
22
|
-
|
141
|
+
def general_num_to_numeral(x, rounding, all_digits)
|
142
|
+
sign, coefficient, exponent = @context.split(x)
|
143
|
+
# the actual number of digits is x.split[1].size
|
144
|
+
# but BigDecimal doesn't keep trailing zeros
|
145
|
+
# we'll use the internal precision which is an implementation detail
|
146
|
+
precision = x.precs.first
|
147
|
+
output_base = rounding.base
|
148
|
+
|
149
|
+
# here rounding_mode is not the output rounding mode, but the rounding mode used for input
|
150
|
+
rounding_mode = (@input_rounding || rounding).mode
|
151
|
+
|
152
|
+
# The minimum exponent of BigDecimal numbers is not well defined;
|
153
|
+
# depends of host architecture, version of BigDecimal, etc.
|
154
|
+
# We'll use an arbitrary conservative value.
|
155
|
+
min_exp = -100000000
|
156
|
+
formatter = Flt::Support::Formatter.new(
|
157
|
+
@context.radix, min_exp, output_base, raise_on_repeat: false
|
158
|
+
)
|
159
|
+
formatter.format(
|
160
|
+
x, coefficient, exponent, rounding_mode, precision, all_digits
|
161
|
+
)
|
162
|
+
|
163
|
+
dec_pos, digits = formatter.digits
|
23
164
|
|
165
|
+
normalization = :approximate
|
166
|
+
|
167
|
+
numeral = Numerals::Numeral[digits, sign: sign, point: dec_pos, rep_pos: formatter.repeat, base: output_base, normalize: normalization]
|
168
|
+
|
169
|
+
numeral = rounding.round(numeral, round_up: formatter.round_up)
|
170
|
+
|
171
|
+
numeral
|
172
|
+
end
|
173
|
+
|
174
|
+
def special_numeral_to_num(numeral)
|
175
|
+
case numeral.special
|
176
|
+
when :nan
|
177
|
+
@context.nan
|
178
|
+
when :inf
|
179
|
+
@context.infinity numeral.sign
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def fixed_numeral_to_num(numeral)
|
184
|
+
# consider:
|
185
|
+
# return exact_numeral_to_num(numeral) if numeral.exact?
|
186
|
+
if numeral.base == 10
|
187
|
+
unless @context.exact?
|
188
|
+
rounding = Rounding[@context.rounding, precision: @context.precision, base: @context.radix]
|
189
|
+
numeral = rounding.round(numeral)
|
190
|
+
end
|
191
|
+
same_base_numeral_to_num numeral
|
192
|
+
else
|
193
|
+
general_numeral_to_num numeral, :fixed
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def same_base_numeral_to_num(numeral)
|
198
|
+
sign, coefficient, scale = numeral.split
|
199
|
+
@context.Num sign, coefficient, scale
|
200
|
+
end
|
201
|
+
|
202
|
+
def exact_numeral_to_num(numeral)
|
203
|
+
@context.Num Rational(*numeral.to_quotient), :fixed
|
204
|
+
end
|
205
|
+
|
206
|
+
def free_numeral_to_num(numeral)
|
207
|
+
general_numeral_to_num numeral, :free
|
208
|
+
end
|
209
|
+
|
210
|
+
def general_numeral_to_num(numeral, mode)
|
211
|
+
sign, coefficient, scale = numeral.split
|
212
|
+
reader = Flt::Support::Reader.new(mode: mode)
|
213
|
+
if @input_rounding
|
214
|
+
rounding_mode = @input_rounding.mode
|
215
|
+
else
|
216
|
+
rounding_Mode = @context.rounding
|
217
|
+
end
|
218
|
+
dec_num_context = Flt::DecNum::Context(
|
219
|
+
precision: @context.precision,
|
220
|
+
rounding: @context.rounding
|
221
|
+
)
|
222
|
+
dec_num = reader.read(dec_num_context, rounding_mode, sign, coefficient, scale, numeral.base)
|
223
|
+
@context.Num dec_num
|
24
224
|
end
|
25
225
|
|
26
226
|
end
|
27
227
|
|
28
|
-
def BigDecimal.numerals_conversion
|
29
|
-
Numerals::BigDecimalConversion.new
|
228
|
+
def BigDecimal.numerals_conversion(options = {})
|
229
|
+
Numerals::BigDecimalConversion.new(options)
|
30
230
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'numerals/conversions'
|
2
|
+
require 'flt'
|
3
|
+
|
4
|
+
# Base class for Conversions of type with context
|
5
|
+
class Numerals::ContextConversion
|
6
|
+
|
7
|
+
def initialize(context_or_type, options={})
|
8
|
+
if Class === context_or_type && context_or_type.respond_to?(:context)
|
9
|
+
@type = context_or_type
|
10
|
+
@context = @type.context
|
11
|
+
elsif context_or_type.respond_to?(:num_class)
|
12
|
+
@context = context_or_type
|
13
|
+
@type = @context.num_class
|
14
|
+
else
|
15
|
+
raise "Invalid Conversion definition"
|
16
|
+
end
|
17
|
+
self.input_rounding = options[:input_rounding]
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_reader :context, :type, :input_rounding
|
21
|
+
|
22
|
+
def input_rounding=(rounding)
|
23
|
+
if rounding
|
24
|
+
if rounding == :context
|
25
|
+
@input_rounding = Rounding[@context.rounding, precision: @context.precision, base: @context.radix]
|
26
|
+
else
|
27
|
+
rounding = Rounding[base: @context.radix].set!(rounding)
|
28
|
+
if rounding.base == @context.radix
|
29
|
+
@input_rounding = rounding
|
30
|
+
else
|
31
|
+
# The rounding precision is not meaningful for the destination type on input
|
32
|
+
@input_rounding = Rounding[rounding.mode, base: @context.radix]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
else
|
36
|
+
@input_rounding = nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|