numerals 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,277 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'helper.rb'))
2
+
3
+ require 'numerals'
4
+ include Numerals
5
+
6
+ class TestFltConversions < Test::Unit::TestCase # < Minitest::Test
7
+
8
+ def test_special_binary
9
+
10
+ context = Flt::BinNum.context = Flt::BinNum::FloatContext
11
+ type = Flt::BinNum
12
+
13
+ assert_equal Numeral.nan, Conversions.number_to_numeral(context.nan)
14
+ assert_equal Numeral.nan, Conversions.number_to_numeral(context.nan, :fixed, Rounding[:exact, base: 2])
15
+ assert_equal Numeral.nan, Conversions.number_to_numeral(context.nan, :fixed, Rounding[:exact, base: 10])
16
+ assert_equal Numeral.nan, Conversions.number_to_numeral(context.nan, :fixed, Rounding[precision: 10, base: 10])
17
+ assert_equal Numeral.nan, Conversions.number_to_numeral(context.nan, :free)
18
+
19
+ assert_equal Numeral.infinity, Conversions.number_to_numeral(context.infinity)
20
+ assert_equal Numeral.infinity, Conversions.number_to_numeral(context.infinity, :fixed, Rounding[:exact, base: 2])
21
+ assert_equal Numeral.infinity, Conversions.number_to_numeral(context.infinity, :fixed, Rounding[:exact, base: 10])
22
+ assert_equal Numeral.infinity, Conversions.number_to_numeral(context.infinity, :fixed, Rounding[precision: 10, base: 10])
23
+ assert_equal Numeral.infinity, Conversions.number_to_numeral(context.infinity, :free)
24
+
25
+ assert_equal Numeral.infinity(-1), Conversions.number_to_numeral(context.infinity(-1))
26
+ assert_equal Numeral.infinity(-1), Conversions.number_to_numeral(context.infinity(-1), :fixed, Rounding[:exact, base: 2])
27
+ assert_equal Numeral.infinity(-1), Conversions.number_to_numeral(context.infinity(-1), :fixed, Rounding[:exact, base: 10])
28
+ assert_equal Numeral.infinity(-1), Conversions.number_to_numeral(context.infinity(-1), :fixed, Rounding[precision: 10, base: 10])
29
+ assert_equal Numeral.infinity(-1), Conversions.number_to_numeral(context.infinity(-1), :free)
30
+
31
+ assert Conversions.numeral_to_number(Numeral.nan, type).nan?
32
+ assert_equal context.infinity, Conversions.numeral_to_number(Numeral.infinity, type)
33
+ assert_equal context.infinity(-1), Conversions.numeral_to_number(Numeral.infinity(-1), type)
34
+ end
35
+
36
+ def test_exact_binary
37
+ one = nil
38
+ context = Flt::BinNum::FloatContext
39
+ Flt::BinNum.context(context) do
40
+ one = Flt::BinNum(1, :fixed)
41
+ end
42
+ rounding = Rounding[:exact, base: 10]
43
+ assert_equal Numeral[1, point: 1],
44
+ Conversions.number_to_numeral(one, :fixed, rounding)
45
+ assert_equal Numeral[1, point: 1, sign: -1],
46
+ Conversions.number_to_numeral(-one, :fixed, rounding)
47
+
48
+ rounding_2 = Rounding[:exact, base: 2]
49
+ assert_equal Numeral[1, point: 1, base: 2],
50
+ Conversions.number_to_numeral(one, :fixed, rounding_2)
51
+ assert_equal Numeral[1, point: 1, sign: -1, base: 2],
52
+ Conversions.number_to_numeral(-one, :fixed, rounding_2)
53
+
54
+ [0.1, 0.01, 0.001, 1/3.0, 10/3.0, 100/3.0, Math::PI,
55
+ 0.5, 123.0, 123.45, 1.23E32, 1.23E-32].each do |x|
56
+ [x, -x].each do |y|
57
+ y = Flt::BinNum(y)
58
+ numeral = exact_decimal(y)
59
+ rounding = Rounding[:exact, base: 10]
60
+ assert_equal numeral, Conversions.number_to_numeral(y, :fixed, rounding),
61
+ "#{y} to base 10 exact numeral"
62
+ assert_equal y, Conversions.numeral_to_number(numeral, context),
63
+ "#{x} base 10 numeral to float"
64
+ end
65
+ end
66
+ end
67
+
68
+ def test_conversions_by_context
69
+ Flt::DecNum.context(precision: 20) do
70
+ numeral = Numeral[1, point: 0]
71
+ context = Flt::DecNum::ExtendedContext
72
+ converted = Conversions.numeral_to_number(numeral, context, :fixed)
73
+ assert_equal Flt::DecNum('0.100000000'), converted
74
+ assert_equal 9, converted.number_of_digits
75
+ end
76
+ end
77
+
78
+ def test_conversions_by_class
79
+ Flt::DecNum.context(precision: 9) do
80
+ numeral = Numeral[1, point: 0]
81
+ converted = Conversions.numeral_to_number(numeral, Flt::DecNum, :fixed)
82
+ assert_equal Flt::DecNum('0.100000000'), converted
83
+ assert_equal 9, converted.number_of_digits
84
+ end
85
+ end
86
+
87
+
88
+ def test_equidistiant_nearest
89
+ # In IEEEDoubleContext
90
+ # 1E23 is equidistant from 2 Floats: lo & hi
91
+ # one or the other will be chosen based on the rounding mode
92
+
93
+ context = Flt::BinNum::IEEEDoubleContext
94
+
95
+ # 1E23
96
+ numeral = Numeral[1, point: 24]
97
+ # 9.999999999999999E22
98
+ numeral_lo = Numeral[[9]*16, point: 23]
99
+ # 1.0000000000000001E23
100
+ numeral_hi = Numeral[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, point: 24]
101
+
102
+ lo = hi = nil
103
+ Flt::BinNum.context(context) do
104
+ lo = Flt::BinNum('0x1.52d02c7e14af6p+76', :fixed)
105
+ hi = Flt::BinNum('0x1.52d02c7e14af7p+76', :fixed)
106
+ end
107
+
108
+ Flt::BinNum.context(context, rounding: :half_even) do
109
+ x = Conversions.numeral_to_number(numeral, Flt::BinNum, :fixed)
110
+ assert_equal lo, x
111
+ end
112
+ # x = Conversions.numeral_to_number(numeral, context[rounding: :half_even], :fixed)
113
+
114
+ Flt::BinNum.context(context, rounding: :half_down) do
115
+ x = Conversions.numeral_to_number(numeral, Flt::BinNum, :fixed)
116
+ assert_equal lo, x
117
+ end
118
+
119
+ Flt::BinNum.context(context, rounding: :half_up) do
120
+ x = Conversions.numeral_to_number(numeral, Flt::BinNum, :fixed)
121
+ assert_equal hi, x
122
+ end
123
+
124
+ Flt::BinNum.context(context, rounding: :half_even) do
125
+ x = Conversions.numeral_to_number(-numeral, Flt::BinNum, :fixed)
126
+ assert_equal -lo, x
127
+ end
128
+ # x = Conversions.numeral_to_number(numeral, context[rounding: :half_even], :fixed)
129
+
130
+ Flt::BinNum.context(context, rounding: :half_down) do
131
+ x = Conversions.numeral_to_number(-numeral, Flt::BinNum, :fixed)
132
+ assert_equal -lo, x
133
+ end
134
+
135
+ Flt::BinNum.context(context, rounding: :half_up) do
136
+ x = Conversions.numeral_to_number(-numeral, Flt::BinNum, :fixed)
137
+ assert_equal -hi, x
138
+ end
139
+
140
+ rounding = Rounding[:exact]
141
+
142
+ Flt::BinNum.context(context, rounding: :half_down) do
143
+ assert_equal numeral, Conversions.number_to_numeral(lo, :free, rounding)
144
+ end
145
+ Flt::BinNum.context(context, rounding: :half_up) do
146
+ assert_equal numeral_lo, Conversions.number_to_numeral(lo, :free, rounding)
147
+ end
148
+ Flt::BinNum.context(context, rounding: :half_even) do
149
+ assert_equal numeral, Conversions.number_to_numeral(lo, :free, rounding)
150
+ end
151
+
152
+ Flt::BinNum.context(context, rounding: :half_up) do
153
+ assert_equal numeral, Conversions.number_to_numeral(hi, :free, rounding)
154
+ end
155
+ Flt::BinNum.context(context, rounding: :half_down) do
156
+ assert_equal numeral_hi, Conversions.number_to_numeral(hi, :free, rounding)
157
+ end
158
+ Flt::BinNum.context(context, rounding: :half_even) do
159
+ assert_equal numeral_hi, Conversions.number_to_numeral(hi, :free, rounding)
160
+ end
161
+
162
+ Flt::BinNum.context(context, rounding: :half_down) do
163
+ assert_equal -numeral, Conversions.number_to_numeral(-lo, :free, rounding)
164
+ end
165
+ Flt::BinNum.context(context, rounding: :half_up) do
166
+ assert_equal -numeral_lo, Conversions.number_to_numeral(-lo, :free, rounding)
167
+ end
168
+ Flt::BinNum.context(context, rounding: :half_even) do
169
+ assert_equal -numeral, Conversions.number_to_numeral(-lo, :free, rounding)
170
+ end
171
+
172
+ Flt::BinNum.context(context, rounding: :half_up) do
173
+ assert_equal -numeral, Conversions.number_to_numeral(-hi, :free, rounding)
174
+ end
175
+ Flt::BinNum.context(context, rounding: :half_down) do
176
+ assert_equal -numeral_hi, Conversions.number_to_numeral(-hi, :free, rounding)
177
+ end
178
+ Flt::BinNum.context(context, rounding: :half_even) do
179
+ assert_equal -numeral_hi, Conversions.number_to_numeral(-hi, :free, rounding)
180
+ end
181
+ end
182
+
183
+ def test_single_nearest
184
+ # In IEEEDoubleContext
185
+ # 64.1 between the floats lo, hi, but is closer to lo
186
+ # So there's a closet Float that should be chosen for rounding
187
+
188
+ context = Flt::BinNum::IEEEDoubleContext
189
+
190
+ numeral = Numeral[6, 4, 1, point: 2]
191
+ numeral_lo = Numeral[6, 4, 0, 9, 9, 9 ,9, 9, 9, 9, 9, 9, 9, 9, 9, 9, point: 2]
192
+
193
+ lo = hi = nil
194
+ Flt::BinNum.context(context) do
195
+ lo = Flt::BinNum('0x1.0066666666666p+6', :fixed) # this is nearer to the 64.1 Float
196
+ hi = Flt::BinNum('0x1.0066666666667p+6', :fixed)
197
+ end
198
+
199
+ Flt::BinNum.context(context, rounding: :half_even) do
200
+ x = Conversions.numeral_to_number(numeral, Flt::BinNum, :fixed)
201
+ assert_equal lo, x
202
+ end
203
+ Flt::BinNum.context(context, rounding: :half_down) do
204
+ x = Conversions.numeral_to_number(numeral, Flt::BinNum, :fixed)
205
+ assert_equal lo, x
206
+ end
207
+ Flt::BinNum.context(context, rounding: :half_up) do
208
+ x = Conversions.numeral_to_number(numeral, Flt::BinNum, :fixed)
209
+ assert_equal lo, x
210
+ end
211
+
212
+ Flt::BinNum.context(context, rounding: :half_even) do
213
+ x = Conversions.numeral_to_number(-numeral, Flt::BinNum, :fixed)
214
+ assert_equal -lo, x
215
+ end
216
+ Flt::BinNum.context(context, rounding: :half_down) do
217
+ x = Conversions.numeral_to_number(-numeral, Flt::BinNum, :fixed)
218
+ assert_equal -lo, x
219
+ end
220
+ Flt::BinNum.context(context, rounding: :half_up) do
221
+ x = Conversions.numeral_to_number(-numeral, Flt::BinNum, :fixed)
222
+ assert_equal -lo, x
223
+ end
224
+
225
+ rounding = Rounding[:exact]
226
+ rounding_16 = Rounding[:half_even, precision: 16]
227
+
228
+ Flt::BinNum.context(context, rounding: :half_even) do
229
+ assert_equal numeral, Conversions.number_to_numeral(lo, :free, rounding)
230
+ end
231
+ Flt::BinNum.context(context, rounding: :half_even) do
232
+ assert_equal numeral_lo, Conversions.number_to_numeral(lo, :free, rounding_16)
233
+ end
234
+ Flt::BinNum.context(context, rounding: :half_down) do
235
+ assert_equal numeral, Conversions.number_to_numeral(lo, :free, rounding)
236
+ end
237
+ Flt::BinNum.context(context, rounding: :half_down) do
238
+ assert_equal numeral_lo, Conversions.number_to_numeral(lo, :free, rounding_16)
239
+ end
240
+ Flt::BinNum.context(context, rounding: :half_up) do
241
+ assert_equal numeral, Conversions.number_to_numeral(lo, :free, rounding)
242
+ end
243
+ Flt::BinNum.context(context, rounding: :half_up) do
244
+ assert_equal numeral_lo, Conversions.number_to_numeral(lo, :free, rounding_16)
245
+ end
246
+
247
+ Flt::BinNum.context(context, rounding: :half_even) do
248
+ assert_equal -numeral, Conversions.number_to_numeral(-lo, :free, rounding)
249
+ end
250
+ Flt::BinNum.context(context, rounding: :half_even) do
251
+ assert_equal -numeral_lo, Conversions.number_to_numeral(-lo, :free, rounding_16)
252
+ end
253
+ Flt::BinNum.context(context, rounding: :half_down) do
254
+ assert_equal -numeral, Conversions.number_to_numeral(-lo, :free, rounding)
255
+ end
256
+ Flt::BinNum.context(context, rounding: :half_down) do
257
+ assert_equal -numeral_lo, Conversions.number_to_numeral(-lo, :free, rounding_16)
258
+ end
259
+ Flt::BinNum.context(context, rounding: :half_up) do
260
+ assert_equal -numeral, Conversions.number_to_numeral(-lo, :free, rounding)
261
+ end
262
+ Flt::BinNum.context(context, rounding: :half_up) do
263
+ assert_equal -numeral_lo, Conversions.number_to_numeral(-lo, :free, rounding_16)
264
+ end
265
+ end
266
+
267
+
268
+ def exact_decimal(x)
269
+ Flt::DecNum.context(exact: true){
270
+ Flt::BinNum.context(Flt::BinNum::FloatContext){
271
+ d = Flt::BinNum(x).to_decimal_exact
272
+ Numeral[d.coefficient.to_s.chars.map(&:to_i), sign: d.sign, point: d.fractional_exponent, normalize: :exact]
273
+ }
274
+ }
275
+ end
276
+
277
+ end
@@ -0,0 +1,50 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),'helper.rb'))
2
+
3
+ require 'numerals'
4
+ include Numerals
5
+
6
+ class TestIntegerConversions < Test::Unit::TestCase # < Minitest::Test
7
+
8
+ def test_special
9
+ assert_raise(ZeroDivisionError){ Conversions.numeral_to_number(Numeral.nan, Integer) }
10
+ assert_raise(ZeroDivisionError){ Conversions.numeral_to_number(Numeral.infinity, Integer) }
11
+ assert_raise(ZeroDivisionError){ Conversions.numeral_to_number(Numeral.infinity(-1), Integer) }
12
+ end
13
+
14
+ def test_integer_to_numeral
15
+ exact = Rounding[:exact]
16
+ nine_digits = Rounding[:half_even, precision: 9]
17
+
18
+ assert_equal Numeral[1, point: 1], Conversions.number_to_numeral(1)
19
+ assert_equal Numeral[1, point: 1], Conversions.number_to_numeral(1, exact)
20
+ assert_equal Numeral[1, 0, 0, 0, 0, 0, 0, 0, 0, point: 1],
21
+ Conversions.number_to_numeral(1, nine_digits)
22
+
23
+ assert_equal Numeral[1, point: 1, sign: -1], Conversions.number_to_numeral(-1)
24
+ assert_equal Numeral[1, point: 1, sign: -1], Conversions.number_to_numeral(-1, exact)
25
+ assert_equal Numeral[1, 0, 0, 0, 0, 0, 0, 0, 0, point: 1, sign: -1],
26
+ Conversions.number_to_numeral(-1, nine_digits)
27
+
28
+ assert_equal Numeral[4, 2, point: 2], Conversions.number_to_numeral(42)
29
+ assert_equal Numeral[4, 2, point: 2], Conversions.number_to_numeral(42, exact)
30
+ assert_equal Numeral[4, 2, 0, 0, 0, 0, 0, 0, 0, point: 2],
31
+ Conversions.number_to_numeral(42, nine_digits)
32
+ end
33
+
34
+ def test_numeral_to_rational
35
+ assert_raise IntegerConversion::InvalidConversion do
36
+ Conversions.numeral_to_number(Numeral[3, point: 0, repeat: 0], Integer)
37
+ end
38
+ assert_raise IntegerConversion::InvalidConversion do
39
+ Conversions.numeral_to_number(Numeral[[3]*9, point: 0, normalize: :approximate], Integer)
40
+ end
41
+ assert_raise IntegerConversion::InvalidConversion do
42
+ Conversions.numeral_to_number(Numeral[1, point: 0], Integer)
43
+ end
44
+ assert_equal 1, Conversions.numeral_to_number(Numeral[1, point: 1], Integer)
45
+ assert_equal -1, Conversions.numeral_to_number(Numeral[1, point: 1, sign: -1], Integer)
46
+ assert_equal 42,
47
+ Conversions.numeral_to_number(Numeral[4, 2, point: 2], Integer)
48
+ end
49
+
50
+ end