1require_relative "testbase"
2require_relative "../ruby/envutil"
3
4require 'thread'
5
6class TestBigDecimal < Test::Unit::TestCase
7  include TestBigDecimalBase
8
9  ROUNDING_MODE_MAP = [
10    [ BigDecimal::ROUND_UP,        :up],
11    [ BigDecimal::ROUND_DOWN,      :down],
12    [ BigDecimal::ROUND_DOWN,      :truncate],
13    [ BigDecimal::ROUND_HALF_UP,   :half_up],
14    [ BigDecimal::ROUND_HALF_UP,   :default],
15    [ BigDecimal::ROUND_HALF_DOWN, :half_down],
16    [ BigDecimal::ROUND_HALF_EVEN, :half_even],
17    [ BigDecimal::ROUND_HALF_EVEN, :banker],
18    [ BigDecimal::ROUND_CEILING,   :ceiling],
19    [ BigDecimal::ROUND_CEILING,   :ceil],
20    [ BigDecimal::ROUND_FLOOR,     :floor],
21  ]
22
23  def assert_nan(x)
24    assert(x.nan?, "Expected #{x.inspect} to be NaN")
25  end
26
27  def assert_positive_infinite(x)
28    assert(x.infinite?, "Expected #{x.inspect} to be positive infinite")
29    assert_operator(x, :>, 0)
30  end
31
32  def assert_negative_infinite(x)
33    assert(x.infinite?, "Expected #{x.inspect} to be negative infinite")
34    assert_operator(x, :<, 0)
35  end
36
37  def assert_positive_zero(x)
38    assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, x.sign,
39                 "Expected #{x.inspect} to be positive zero")
40  end
41
42  def assert_negative_zero(x)
43    assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, x.sign,
44                 "Expected #{x.inspect} to be negative zero")
45  end
46
47  def test_not_equal
48    assert_not_equal BigDecimal("1"), BigDecimal.allocate
49  end
50
51  def test_global_new
52    assert_equal(1, BigDecimal("1"))
53    assert_equal(1, BigDecimal("1", 1))
54    assert_raise(ArgumentError) { BigDecimal("1", -1) }
55    assert_raise(ArgumentError) { BigDecimal(4.2) }
56    begin
57      BigDecimal(4.2)
58    rescue ArgumentError => error
59      assert_match(/Float/, error.message)
60    end
61    assert_raise(ArgumentError) { BigDecimal(42.quo(7)) }
62    begin
63      BigDecimal(42.quo(7))
64    rescue ArgumentError => error
65      assert_match(/Rational/, error.message)
66    end
67  end
68
69  def test_global_new_with_integer
70    assert_equal(BigDecimal("1"), BigDecimal(1))
71    assert_equal(BigDecimal("-1"), BigDecimal(-1))
72    assert_equal(BigDecimal((2**100).to_s), BigDecimal(2**100))
73    assert_equal(BigDecimal((-2**100).to_s), BigDecimal(-2**100))
74  end
75
76  def test_global_new_with_rational
77    assert_equal(BigDecimal("0.333333333333333333333"), BigDecimal(1.quo(3), 21))
78    assert_equal(BigDecimal("-0.333333333333333333333"), BigDecimal(-1.quo(3), 21))
79    assert_raise(ArgumentError) { BigDecimal(1.quo(3)) }
80  end
81
82  def test_global_new_with_float
83    assert_equal(BigDecimal("0.1235"), BigDecimal(0.1234567, 4))
84    assert_equal(BigDecimal("-0.1235"), BigDecimal(-0.1234567, 4))
85    assert_raise(ArgumentError) { BigDecimal(0.1) }
86    assert_raise(ArgumentError) { BigDecimal(0.1, Float::DIG + 2) }
87    assert_nothing_raised { BigDecimal(0.1, Float::DIG + 1) }
88  end
89
90  def test_global_new_with_big_decimal
91    assert_equal(BigDecimal(1), BigDecimal(BigDecimal(1)))
92    assert_equal(BigDecimal('+0'), BigDecimal(BigDecimal('+0')))
93    assert_equal(BigDecimal('-0'), BigDecimal(BigDecimal('-0')))
94    BigDecimal.save_exception_mode do
95      BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
96      BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
97      assert_positive_infinite(BigDecimal(BigDecimal('Infinity')))
98      assert_negative_infinite(BigDecimal(BigDecimal('-Infinity')))
99      assert_nan(BigDecimal(BigDecimal('NaN')))
100    end
101  end
102
103  def test_global_new_with_tainted_string
104    Thread.new {
105      $SAFE = 1
106      BigDecimal('1'.taint)
107    }.join
108  end
109
110  def test_new
111    assert_equal(1, BigDecimal.new("1"))
112    assert_equal(1, BigDecimal.new("1", 1))
113    assert_equal(1, BigDecimal.new(" 1 "))
114    assert_equal(111, BigDecimal.new("1_1_1_"))
115    assert_equal(0, BigDecimal.new("_1_1_1"))
116    assert_equal(10**(-1), BigDecimal.new("1E-1"), '#4825')
117
118    BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
119    BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
120    assert_equal( 1, BigDecimal.new("Infinity").infinite?)
121    assert_equal(-1, BigDecimal.new("-Infinity").infinite?)
122    assert_equal(true, BigDecimal.new("NaN").nan?)
123    assert_equal( 1, BigDecimal.new("1E1111111111111111111").infinite?)
124  end
125
126  def test_new_with_integer
127    assert_equal(BigDecimal("1"), BigDecimal.new(1))
128    assert_equal(BigDecimal("-1"), BigDecimal.new(-1))
129    assert_equal(BigDecimal((2**100).to_s), BigDecimal.new(2**100))
130    assert_equal(BigDecimal((-2**100).to_s), BigDecimal.new(-2**100))
131  end
132
133  def test_new_with_rational
134    assert_equal(BigDecimal("0.333333333333333333333"), BigDecimal.new(1.quo(3), 21))
135    assert_equal(BigDecimal("-0.333333333333333333333"), BigDecimal.new(-1.quo(3), 21))
136    assert_raise(ArgumentError) { BigDecimal.new(1.quo(3)) }
137  end
138
139  def test_new_with_float
140    assert_equal(BigDecimal("0.1235"), BigDecimal(0.1234567, 4))
141    assert_equal(BigDecimal("-0.1235"), BigDecimal(-0.1234567, 4))
142    assert_raise(ArgumentError) { BigDecimal.new(0.1) }
143    assert_raise(ArgumentError) { BigDecimal.new(0.1, Float::DIG + 2) }
144    assert_nothing_raised { BigDecimal.new(0.1, Float::DIG + 1) }
145  end
146
147  def test_new_with_big_decimal
148    assert_equal(BigDecimal(1), BigDecimal.new(BigDecimal(1)))
149    assert_equal(BigDecimal('+0'), BigDecimal.new(BigDecimal('+0')))
150    assert_equal(BigDecimal('-0'), BigDecimal.new(BigDecimal('-0')))
151    BigDecimal.save_exception_mode do
152      BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
153      BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
154      assert_positive_infinite(BigDecimal.new(BigDecimal('Infinity')))
155      assert_negative_infinite(BigDecimal.new(BigDecimal('-Infinity')))
156      assert_nan(BigDecimal(BigDecimal.new('NaN')))
157    end
158  end
159
160  def test_new_with_tainted_string
161    Thread.new {
162      $SAFE = 1
163      BigDecimal.new('1'.taint)
164    }.join
165  end
166
167  def _test_mode(type)
168    BigDecimal.mode(type, true)
169    assert_raise(FloatDomainError) { yield }
170
171    BigDecimal.mode(type, false)
172    assert_nothing_raised { yield }
173  end
174
175  def test_mode
176    assert_raise(ArgumentError) { BigDecimal.mode(BigDecimal::EXCEPTION_ALL, 1) }
177    assert_raise(ArgumentError) { BigDecimal.mode(BigDecimal::ROUND_MODE, 256) }
178    assert_raise(ArgumentError) { BigDecimal.mode(BigDecimal::ROUND_MODE, :xyzzy) }
179    assert_raise(TypeError) { BigDecimal.mode(0xf000, true) }
180
181    begin
182      saved_mode = BigDecimal.mode(BigDecimal::ROUND_MODE)
183
184      [ BigDecimal::ROUND_UP,
185        BigDecimal::ROUND_DOWN,
186        BigDecimal::ROUND_HALF_UP,
187        BigDecimal::ROUND_HALF_DOWN,
188        BigDecimal::ROUND_CEILING,
189        BigDecimal::ROUND_FLOOR,
190        BigDecimal::ROUND_HALF_EVEN,
191      ].each do |mode|
192        BigDecimal.mode(BigDecimal::ROUND_MODE, mode)
193        assert_equal(mode, BigDecimal.mode(BigDecimal::ROUND_MODE))
194      end
195    ensure
196      BigDecimal.mode(BigDecimal::ROUND_MODE, saved_mode)
197    end
198
199    BigDecimal.save_rounding_mode do
200      ROUNDING_MODE_MAP.each do |const, sym|
201        BigDecimal.mode(BigDecimal::ROUND_MODE, sym)
202        assert_equal(const, BigDecimal.mode(BigDecimal::ROUND_MODE))
203      end
204    end
205  end
206
207  def test_thread_local_mode
208    begin
209      saved_mode = BigDecimal.mode(BigDecimal::ROUND_MODE)
210
211      BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_UP)
212      Thread.start {
213        BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN)
214        assert_equal(BigDecimal::ROUND_HALF_EVEN, BigDecimal.mode(BigDecimal::ROUND_MODE))
215      }.join
216      assert_equal(BigDecimal::ROUND_UP, BigDecimal.mode(BigDecimal::ROUND_MODE))
217    ensure
218      BigDecimal.mode(BigDecimal::ROUND_MODE, saved_mode)
219    end
220  end
221
222  def test_save_exception_mode
223    BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
224    mode = BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW)
225    BigDecimal.save_exception_mode do
226      BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, true)
227    end
228    assert_equal(mode, BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW))
229
230    BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_FLOOR)
231    BigDecimal.save_exception_mode do
232      BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN)
233    end
234    assert_equal(BigDecimal::ROUND_HALF_EVEN, BigDecimal.mode(BigDecimal::ROUND_MODE))
235
236    assert_equal(42, BigDecimal.save_exception_mode { 42 })
237  end
238
239  def test_save_rounding_mode
240    BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_FLOOR)
241    BigDecimal.save_rounding_mode do
242      BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN)
243    end
244    assert_equal(BigDecimal::ROUND_FLOOR, BigDecimal.mode(BigDecimal::ROUND_MODE))
245
246    assert_equal(42, BigDecimal.save_rounding_mode { 42 })
247  end
248
249  def test_save_limit
250    begin
251      old = BigDecimal.limit
252      BigDecimal.limit(100)
253      BigDecimal.save_limit do
254        BigDecimal.limit(200)
255      end
256      assert_equal(100, BigDecimal.limit);
257    ensure
258      BigDecimal.limit(old)
259    end
260
261    assert_equal(42, BigDecimal.save_limit { 42 })
262  end
263
264  def test_exception_nan
265    _test_mode(BigDecimal::EXCEPTION_NaN) { BigDecimal.new("NaN") }
266  end
267
268  def test_exception_infinity
269    _test_mode(BigDecimal::EXCEPTION_INFINITY) { BigDecimal.new("Infinity") }
270  end
271
272  def test_exception_underflow
273    _test_mode(BigDecimal::EXCEPTION_UNDERFLOW) do
274      x = BigDecimal.new("0.1")
275      100.times do
276        x *= x
277      end
278    end
279  end
280
281  def test_exception_overflow
282    _test_mode(BigDecimal::EXCEPTION_OVERFLOW) do
283      x = BigDecimal.new("10")
284      100.times do
285        x *= x
286      end
287    end
288  end
289
290  def test_exception_zerodivide
291    BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
292    _test_mode(BigDecimal::EXCEPTION_ZERODIVIDE) { 1 / BigDecimal.new("0") }
293    _test_mode(BigDecimal::EXCEPTION_ZERODIVIDE) { -1 / BigDecimal.new("0") }
294  end
295
296  def test_round_up
297    n4 = BigDecimal.new("4") # n4 / 9 = 0.44444...
298    n5 = BigDecimal.new("5") # n5 / 9 = 0.55555...
299    n6 = BigDecimal.new("6") # n6 / 9 = 0.66666...
300    m4, m5, m6 = -n4, -n5, -n6
301    n2h = BigDecimal.new("2.5")
302    n3h = BigDecimal.new("3.5")
303    m2h, m3h = -n2h, -n3h
304
305    BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_UP)
306    assert_operator(n4, :<, n4 / 9 * 9)
307    assert_operator(n5, :<, n5 / 9 * 9)
308    assert_operator(n6, :<, n6 / 9 * 9)
309    assert_operator(m4, :>, m4 / 9 * 9)
310    assert_operator(m5, :>, m5 / 9 * 9)
311    assert_operator(m6, :>, m6 / 9 * 9)
312    assert_equal(3, n2h.round)
313    assert_equal(4, n3h.round)
314    assert_equal(-3, m2h.round)
315    assert_equal(-4, m3h.round)
316
317    BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_DOWN)
318    assert_operator(n4, :>, n4 / 9 * 9)
319    assert_operator(n5, :>, n5 / 9 * 9)
320    assert_operator(n6, :>, n6 / 9 * 9)
321    assert_operator(m4, :<, m4 / 9 * 9)
322    assert_operator(m5, :<, m5 / 9 * 9)
323    assert_operator(m6, :<, m6 / 9 * 9)
324    assert_equal(2, n2h.round)
325    assert_equal(3, n3h.round)
326    assert_equal(-2, m2h.round)
327    assert_equal(-3, m3h.round)
328
329    BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_UP)
330    assert_operator(n4, :>, n4 / 9 * 9)
331    assert_operator(n5, :<, n5 / 9 * 9)
332    assert_operator(n6, :<, n6 / 9 * 9)
333    assert_operator(m4, :<, m4 / 9 * 9)
334    assert_operator(m5, :>, m5 / 9 * 9)
335    assert_operator(m6, :>, m6 / 9 * 9)
336    assert_equal(3, n2h.round)
337    assert_equal(4, n3h.round)
338    assert_equal(-3, m2h.round)
339    assert_equal(-4, m3h.round)
340
341    BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_DOWN)
342    assert_operator(n4, :>, n4 / 9 * 9)
343    assert_operator(n5, :>, n5 / 9 * 9)
344    assert_operator(n6, :<, n6 / 9 * 9)
345    assert_operator(m4, :<, m4 / 9 * 9)
346    assert_operator(m5, :<, m5 / 9 * 9)
347    assert_operator(m6, :>, m6 / 9 * 9)
348    assert_equal(2, n2h.round)
349    assert_equal(3, n3h.round)
350    assert_equal(-2, m2h.round)
351    assert_equal(-3, m3h.round)
352
353    BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN)
354    assert_operator(n4, :>, n4 / 9 * 9)
355    assert_operator(n5, :<, n5 / 9 * 9)
356    assert_operator(n6, :<, n6 / 9 * 9)
357    assert_operator(m4, :<, m4 / 9 * 9)
358    assert_operator(m5, :>, m5 / 9 * 9)
359    assert_operator(m6, :>, m6 / 9 * 9)
360    assert_equal(2, n2h.round)
361    assert_equal(4, n3h.round)
362    assert_equal(-2, m2h.round)
363    assert_equal(-4, m3h.round)
364
365    BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_CEILING)
366    assert_operator(n4, :<, n4 / 9 * 9)
367    assert_operator(n5, :<, n5 / 9 * 9)
368    assert_operator(n6, :<, n6 / 9 * 9)
369    assert_operator(m4, :<, m4 / 9 * 9)
370    assert_operator(m5, :<, m5 / 9 * 9)
371    assert_operator(m6, :<, m6 / 9 * 9)
372    assert_equal(3, n2h.round)
373    assert_equal(4, n3h.round)
374    assert_equal(-2, m2h.round)
375    assert_equal(-3, m3h.round)
376
377    BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_FLOOR)
378    assert_operator(n4, :>, n4 / 9 * 9)
379    assert_operator(n5, :>, n5 / 9 * 9)
380    assert_operator(n6, :>, n6 / 9 * 9)
381    assert_operator(m4, :>, m4 / 9 * 9)
382    assert_operator(m5, :>, m5 / 9 * 9)
383    assert_operator(m6, :>, m6 / 9 * 9)
384    assert_equal(2, n2h.round)
385    assert_equal(3, n3h.round)
386    assert_equal(-3, m2h.round)
387    assert_equal(-4, m3h.round)
388  end
389
390  def test_zero_p
391    assert_equal(true, BigDecimal.new("0").zero?)
392    assert_equal(false, BigDecimal.new("1").zero?)
393    assert_equal(true, BigDecimal.new("0E200000000000000").zero?)
394  end
395
396  def test_nonzero_p
397    assert_equal(nil, BigDecimal.new("0").nonzero?)
398    assert_equal(BigDecimal.new("1"), BigDecimal.new("1").nonzero?)
399  end
400
401  def test_double_fig
402    assert_kind_of(Integer, BigDecimal.double_fig)
403  end
404
405  def test_cmp
406    n1 = BigDecimal.new("1")
407    n2 = BigDecimal.new("2")
408    assert_equal( 0, n1 <=> n1)
409    assert_equal( 1, n2 <=> n1)
410    assert_equal(-1, n1 <=> n2)
411    assert_operator(n1, :==, n1)
412    assert_operator(n1, :!=, n2)
413    assert_operator(n1, :<, n2)
414    assert_operator(n1, :<=, n1)
415    assert_operator(n1, :<=, n2)
416    assert_operator(n2, :>, n1)
417    assert_operator(n2, :>=, n1)
418    assert_operator(n1, :>=, n1)
419
420    assert_operator(BigDecimal.new("-0"), :==, BigDecimal.new("0"))
421    assert_operator(BigDecimal.new("0"), :<, BigDecimal.new("1"))
422    assert_operator(BigDecimal.new("1"), :>, BigDecimal.new("0"))
423    assert_operator(BigDecimal.new("1"), :>, BigDecimal.new("-1"))
424    assert_operator(BigDecimal.new("-1"), :<, BigDecimal.new("1"))
425    assert_operator(BigDecimal.new((2**100).to_s), :>, BigDecimal.new("1"))
426    assert_operator(BigDecimal.new("1"), :<, BigDecimal.new((2**100).to_s))
427
428    BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
429    inf = BigDecimal.new("Infinity")
430    assert_operator(inf, :>, 1)
431    assert_operator(1, :<, inf)
432
433    assert_operator(BigDecimal("1E-1"), :==, 10**(-1), '#4825')
434    assert_equal(0, BigDecimal("1E-1") <=> 10**(-1), '#4825')
435  end
436
437  def test_cmp_nan
438    n1 = BigDecimal.new("1")
439    BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
440    assert_equal(nil, BigDecimal.new("NaN") <=> n1)
441    assert_equal(false, BigDecimal.new("NaN") > n1)
442  end
443
444  def test_cmp_failing_coercion
445    n1 = BigDecimal.new("1")
446    assert_equal(nil, n1 <=> nil)
447    assert_raise(ArgumentError){n1 > nil}
448  end
449
450  def test_cmp_coerce
451    n1 = BigDecimal.new("1")
452    n2 = BigDecimal.new("2")
453    o1 = Object.new; def o1.coerce(x); [x, BigDecimal.new("1")]; end
454    o2 = Object.new; def o2.coerce(x); [x, BigDecimal.new("2")]; end
455    assert_equal( 0, n1 <=> o1)
456    assert_equal( 1, n2 <=> o1)
457    assert_equal(-1, n1 <=> o2)
458    assert_operator(n1, :==, o1)
459    assert_operator(n1, :!=, o2)
460    assert_operator(n1, :<, o2)
461    assert_operator(n1, :<=, o1)
462    assert_operator(n1, :<=, o2)
463    assert_operator(n2, :>, o1)
464    assert_operator(n2, :>=, o1)
465    assert_operator(n1, :>=, 1)
466  end
467
468  def test_cmp_bignum
469    assert_operator(BigDecimal.new((2**100).to_s), :==, 2**100)
470  end
471
472  def test_cmp_data
473    d = Time.now; def d.coerce(x); [x, x]; end
474    assert_operator(BigDecimal.new((2**100).to_s), :==, d)
475  end
476
477  def test_precs
478    a = BigDecimal.new("1").precs
479    assert_instance_of(Array, a)
480    assert_equal(2, a.size)
481    assert_kind_of(Integer, a[0])
482    assert_kind_of(Integer, a[1])
483  end
484
485  def test_hash
486    a = []
487    b = BigDecimal.new("1")
488    10.times { a << b *= 10 }
489    h = {}
490    a.each_with_index {|x, i| h[x] = i }
491    a.each_with_index do |x, i|
492      assert_equal(i, h[x])
493    end
494  end
495
496  def test_marshal
497    s = Marshal.dump(BigDecimal("1", 1))
498    assert_equal(BigDecimal("1", 1), Marshal.load(s))
499
500    # corrupt data
501    s = s.gsub(/BigDecimal.*\z/m) {|x| x.gsub(/\d/m, "-") }
502    assert_raise(TypeError) { Marshal.load(s) }
503  end
504
505  def test_finite_infinite_nan
506    BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
507    BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false)
508
509    x = BigDecimal.new("0")
510    assert_equal(true, x.finite?)
511    assert_equal(nil, x.infinite?)
512    assert_equal(false, x.nan?)
513    y = 1 / x
514    assert_equal(false, y.finite?)
515    assert_equal(1, y.infinite?)
516    assert_equal(false, y.nan?)
517    y = -1 / x
518    assert_equal(false, y.finite?)
519    assert_equal(-1, y.infinite?)
520    assert_equal(false, y.nan?)
521
522    BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
523    y = 0 / x
524    assert_equal(false, y.finite?)
525    assert_equal(nil, y.infinite?)
526    assert_equal(true, y.nan?)
527  end
528
529  def test_to_i
530    BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
531    BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
532
533    x = BigDecimal.new("0")
534    assert_kind_of(Integer, x.to_i)
535    assert_equal(0, x.to_i)
536    assert_raise(FloatDomainError){( 1 / x).to_i}
537    assert_raise(FloatDomainError){(-1 / x).to_i}
538    assert_raise(FloatDomainError) {( 0 / x).to_i}
539    x = BigDecimal.new("1")
540    assert_equal(1, x.to_i)
541    x = BigDecimal.new((2**100).to_s)
542    assert_equal(2**100, x.to_i)
543  end
544
545  def test_to_f
546    BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
547    BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
548    BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false)
549
550    x = BigDecimal.new("0")
551    assert_instance_of(Float, x.to_f)
552    assert_equal(0.0, x.to_f)
553    assert_equal( 1.0 / 0.0, ( 1 / x).to_f)
554    assert_equal(-1.0 / 0.0, (-1 / x).to_f)
555    assert_equal(true, ( 0 / x).to_f.nan?)
556    x = BigDecimal.new("1")
557    assert_equal(1.0, x.to_f)
558    x = BigDecimal.new((2**100).to_s)
559    assert_equal((2**100).to_f, x.to_f)
560    x = BigDecimal.new("1" + "0" * 10000)
561    assert_equal(0, BigDecimal.new("-0").to_f)
562
563    BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, true)
564    assert_raise(FloatDomainError) { x.to_f }
565    BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
566    assert_kind_of(Float,   x .to_f)
567    assert_kind_of(Float, (-x).to_f)
568
569    bug6944 = '[ruby-core:47342]'
570
571    BigDecimal.mode(BigDecimal::EXCEPTION_UNDERFLOW, true)
572    x = "1e#{Float::MIN_10_EXP - 2*Float::DIG}"
573    assert_raise(FloatDomainError, x) {BigDecimal(x).to_f}
574    x = "-#{x}"
575    assert_raise(FloatDomainError, x) {BigDecimal(x).to_f}
576    x = "1e#{Float::MIN_10_EXP - Float::DIG}"
577    assert_nothing_raised(FloatDomainError, x) {
578      assert_in_delta(0.0, BigDecimal(x).to_f, 10**Float::MIN_10_EXP, bug6944)
579    }
580    x = "-#{x}"
581    assert_nothing_raised(FloatDomainError, x) {
582      assert_in_delta(0.0, BigDecimal(x).to_f, 10**Float::MIN_10_EXP, bug6944)
583    }
584
585    BigDecimal.mode(BigDecimal::EXCEPTION_UNDERFLOW, false)
586    x = "1e#{Float::MIN_10_EXP - 2*Float::DIG}"
587    assert_equal( 0.0, BigDecimal(x).to_f, x)
588    x = "-#{x}"
589    assert_equal(-0.0, BigDecimal(x).to_f, x)
590    x = "1e#{Float::MIN_10_EXP - Float::DIG}"
591    assert_nothing_raised(FloatDomainError, x) {
592      assert_in_delta(0.0, BigDecimal(x).to_f, 10**Float::MIN_10_EXP, bug6944)
593    }
594    x = "-#{x}"
595    assert_nothing_raised(FloatDomainError, x) {
596      assert_in_delta(0.0, BigDecimal(x).to_f, 10**Float::MIN_10_EXP, bug6944)
597    }
598
599    assert_equal( 0.0, BigDecimal(  '9e-325').to_f)
600    assert_equal( 0.0, BigDecimal( '10e-325').to_f)
601    assert_equal(-0.0, BigDecimal( '-9e-325').to_f)
602    assert_equal(-0.0, BigDecimal('-10e-325').to_f)
603  end
604
605  def test_coerce
606    a, b = BigDecimal.new("1").coerce(1.0)
607    assert_instance_of(Float, a)
608    assert_instance_of(Float, b)
609    assert_equal(2, 1 + BigDecimal.new("1"), '[ruby-core:25697]')
610
611    a, b = BigDecimal("1").coerce(1.quo(10))
612    assert_equal(BigDecimal("0.1"), a, '[ruby-core:34318]')
613
614    a, b = BigDecimal("0.11111").coerce(1.quo(3))
615    assert_equal(BigDecimal("0." + "3"*a.precs[0]), a)
616
617    assert_nothing_raised(TypeError, '#7176') do
618      BigDecimal.new('1') + Rational(1)
619    end
620  end
621
622  def test_uplus
623    x = BigDecimal.new("1")
624    assert_equal(x, x.send(:+@))
625  end
626
627  def test_add
628    x = BigDecimal.new("1")
629    assert_equal(BigDecimal.new("2"), x + x)
630    assert_equal(1, BigDecimal.new("0") + 1)
631    assert_equal(1, x + 0)
632
633    assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("0") + 0).sign)
634    assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("-0") + 0).sign)
635    assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (BigDecimal.new("-0") + BigDecimal.new("-0")).sign)
636
637    x = BigDecimal.new((2**100).to_s)
638    assert_equal(BigDecimal.new((2**100+1).to_s), x + 1)
639  end
640
641  def test_sub
642    x = BigDecimal.new("1")
643    assert_equal(BigDecimal.new("0"), x - x)
644    assert_equal(-1, BigDecimal.new("0") - 1)
645    assert_equal(1, x - 0)
646
647    assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("0") - 0).sign)
648    assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (BigDecimal.new("-0") - 0).sign)
649    assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("-0") - BigDecimal.new("-0")).sign)
650
651    x = BigDecimal.new((2**100).to_s)
652    assert_equal(BigDecimal.new((2**100-1).to_s), x - 1)
653  end
654
655  def test_sub_with_float
656    assert_kind_of(BigDecimal, BigDecimal.new("3") - 1.0)
657  end
658
659  def test_sub_with_rational
660    assert_kind_of(BigDecimal, BigDecimal.new("3") - 1.quo(3))
661  end
662
663  def test_mult
664    x = BigDecimal.new((2**100).to_s)
665    assert_equal(BigDecimal.new((2**100 * 3).to_s), (x * 3).to_i)
666    assert_equal(x, (x * 1).to_i)
667    assert_equal(x, (BigDecimal("1") * x).to_i)
668    assert_equal(BigDecimal.new((2**200).to_s), (x * x).to_i)
669  end
670
671  def test_mult_with_float
672    assert_kind_of(BigDecimal, BigDecimal.new("3") * 1.5)
673  end
674
675  def test_mult_with_rational
676    assert_kind_of(BigDecimal, BigDecimal.new("3") * 1.quo(3))
677  end
678
679  def test_div
680    x = BigDecimal.new((2**100).to_s)
681    assert_equal(BigDecimal.new((2**100 / 3).to_s), (x / 3).to_i)
682    assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("0") / 1).sign)
683    assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (BigDecimal.new("-0") / 1).sign)
684    assert_equal(2, BigDecimal.new("2") / 1)
685    assert_equal(-2, BigDecimal.new("2") / -1)
686  end
687
688  def test_div_with_float
689    assert_kind_of(BigDecimal, BigDecimal.new("3") / 1.5)
690  end
691
692  def test_div_with_rational
693    assert_kind_of(BigDecimal, BigDecimal.new("3") / 1.quo(3))
694  end
695
696  def test_mod
697    x = BigDecimal.new((2**100).to_s)
698    assert_equal(1, x % 3)
699    assert_equal(2, (-x) % 3)
700    assert_equal(-2, x % -3)
701    assert_equal(-1, (-x) % -3)
702  end
703
704  def test_mod_with_float
705    assert_kind_of(BigDecimal, BigDecimal.new("3") % 1.5)
706  end
707
708  def test_mod_with_rational
709    assert_kind_of(BigDecimal, BigDecimal.new("3") % 1.quo(3))
710  end
711
712  def test_remainder
713    x = BigDecimal.new((2**100).to_s)
714    assert_equal(1, x.remainder(3))
715    assert_equal(-1, (-x).remainder(3))
716    assert_equal(1, x.remainder(-3))
717    assert_equal(-1, (-x).remainder(-3))
718  end
719
720  def test_remainder_with_float
721    assert_kind_of(BigDecimal, BigDecimal.new("3").remainder(1.5))
722  end
723
724  def test_remainder_with_rational
725    assert_kind_of(BigDecimal, BigDecimal.new("3").remainder(1.quo(3)))
726  end
727
728  def test_divmod
729    x = BigDecimal.new((2**100).to_s)
730    assert_equal([(x / 3).floor, 1], x.divmod(3))
731    assert_equal([(-x / 3).floor, 2], (-x).divmod(3))
732
733    assert_equal([0, 0], BigDecimal.new("0").divmod(2))
734
735    BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
736    assert_raise(ZeroDivisionError){BigDecimal.new("0").divmod(0)}
737  end
738
739  def test_add_bigdecimal
740    x = BigDecimal.new((2**100).to_s)
741    assert_equal(3000000000000000000000000000000, x.add(x, 1))
742    assert_equal(2500000000000000000000000000000, x.add(x, 2))
743    assert_equal(2540000000000000000000000000000, x.add(x, 3))
744  end
745
746  def test_sub_bigdecimal
747    x = BigDecimal.new((2**100).to_s)
748    assert_equal(1000000000000000000000000000000, x.sub(1, 1))
749    assert_equal(1300000000000000000000000000000, x.sub(1, 2))
750    assert_equal(1270000000000000000000000000000, x.sub(1, 3))
751  end
752
753  def test_mult_bigdecimal
754    x = BigDecimal.new((2**100).to_s)
755    assert_equal(4000000000000000000000000000000, x.mult(3, 1))
756    assert_equal(3800000000000000000000000000000, x.mult(3, 2))
757    assert_equal(3800000000000000000000000000000, x.mult(3, 3))
758  end
759
760  def test_div_bigdecimal
761    x = BigDecimal.new((2**100).to_s)
762    assert_equal(422550200076076467165567735125, x.div(3))
763    assert_equal(400000000000000000000000000000, x.div(3, 1))
764    assert_equal(420000000000000000000000000000, x.div(3, 2))
765    assert_equal(423000000000000000000000000000, x.div(3, 3))
766    BigDecimal.save_exception_mode do
767      BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
768      assert_equal(0, BigDecimal("0").div(BigDecimal("Infinity")))
769    end
770  end
771
772  def test_abs_bigdecimal
773    x = BigDecimal.new((2**100).to_s)
774    assert_equal(1267650600228229401496703205376, x.abs)
775    x = BigDecimal.new("-" + (2**100).to_s)
776    assert_equal(1267650600228229401496703205376, x.abs)
777    x = BigDecimal.new("0")
778    assert_equal(0, x.abs)
779    BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
780    x = BigDecimal.new("NaN")
781    assert_equal(true, x.abs.nan?)
782  end
783
784  def test_sqrt_bigdecimal
785    x = BigDecimal.new("0.09")
786    assert_in_delta(0.3, x.sqrt(1), 0.001)
787    x = BigDecimal.new((2**100).to_s)
788    y = BigDecimal("1125899906842624")
789    e = y.exponent
790    assert_equal(true, (x.sqrt(100) - y).abs < BigDecimal("1E#{e-100}"))
791    assert_equal(true, (x.sqrt(200) - y).abs < BigDecimal("1E#{e-200}"))
792    assert_equal(true, (x.sqrt(300) - y).abs < BigDecimal("1E#{e-300}"))
793    x = BigDecimal.new("-" + (2**100).to_s)
794    assert_raise(FloatDomainError) { x.sqrt(1) }
795    x = BigDecimal.new((2**200).to_s)
796    assert_equal(2**100, x.sqrt(1))
797
798    BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
799    BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
800    assert_raise(FloatDomainError) { BigDecimal.new("NaN").sqrt(1) }
801
802    assert_equal(0, BigDecimal.new("0").sqrt(1))
803    assert_equal(1, BigDecimal.new("1").sqrt(1))
804  end
805
806  def test_fix
807    x = BigDecimal.new("1.1")
808    assert_equal(1, x.fix)
809  end
810
811  def test_frac
812    x = BigDecimal.new("1.1")
813    assert_equal(0.1, x.frac)
814    assert_equal(0.1, BigDecimal.new("0.1").frac)
815    BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
816    assert_equal(true, BigDecimal.new("NaN").frac.nan?)
817  end
818
819  def test_round
820    assert_equal(3, BigDecimal.new("3.14159").round)
821    assert_equal(9, BigDecimal.new("8.7").round)
822    assert_equal(3.142, BigDecimal.new("3.14159").round(3))
823    assert_equal(13300.0, BigDecimal.new("13345.234").round(-2))
824
825    x = BigDecimal.new("111.111")
826    assert_equal(111    , x.round)
827    assert_equal(111.1  , x.round(1))
828    assert_equal(111.11 , x.round(2))
829    assert_equal(111.111, x.round(3))
830    assert_equal(111.111, x.round(4))
831    assert_equal(110    , x.round(-1))
832    assert_equal(100    , x.round(-2))
833    assert_equal(  0    , x.round(-3))
834    assert_equal(  0    , x.round(-4))
835
836    x = BigDecimal.new("2.5")
837    assert_equal(3, x.round(0, BigDecimal::ROUND_UP))
838    assert_equal(2, x.round(0, BigDecimal::ROUND_DOWN))
839    assert_equal(3, x.round(0, BigDecimal::ROUND_HALF_UP))
840    assert_equal(2, x.round(0, BigDecimal::ROUND_HALF_DOWN))
841    assert_equal(2, x.round(0, BigDecimal::ROUND_HALF_EVEN))
842    assert_equal(3, x.round(0, BigDecimal::ROUND_CEILING))
843    assert_equal(2, x.round(0, BigDecimal::ROUND_FLOOR))
844    assert_raise(ArgumentError) { x.round(0, 256) }
845
846    ROUNDING_MODE_MAP.each do |const, sym|
847      assert_equal(x.round(0, const), x.round(0, sym))
848    end
849
850    bug3803 = '[ruby-core:32136]'
851    15.times do |n|
852      x = BigDecimal.new("5#{'0'*n}1")
853      assert_equal(10**(n+2), x.round(-(n+2), BigDecimal::ROUND_HALF_DOWN), bug3803)
854      assert_equal(10**(n+2), x.round(-(n+2), BigDecimal::ROUND_HALF_EVEN), bug3803)
855      x = BigDecimal.new("0.5#{'0'*n}1")
856      assert_equal(1, x.round(0, BigDecimal::ROUND_HALF_DOWN), bug3803)
857      assert_equal(1, x.round(0, BigDecimal::ROUND_HALF_EVEN), bug3803)
858      x = BigDecimal.new("-0.5#{'0'*n}1")
859      assert_equal(-1, x.round(0, BigDecimal::ROUND_HALF_DOWN), bug3803)
860      assert_equal(-1, x.round(0, BigDecimal::ROUND_HALF_EVEN), bug3803)
861    end
862  end
863
864  def test_truncate
865    assert_equal(3, BigDecimal.new("3.14159").truncate)
866    assert_equal(8, BigDecimal.new("8.7").truncate)
867    assert_equal(3.141, BigDecimal.new("3.14159").truncate(3))
868    assert_equal(13300.0, BigDecimal.new("13345.234").truncate(-2))
869  end
870
871  def test_floor
872    assert_equal(3, BigDecimal.new("3.14159").floor)
873    assert_equal(-10, BigDecimal.new("-9.1").floor)
874    assert_equal(3.141, BigDecimal.new("3.14159").floor(3))
875    assert_equal(13300.0, BigDecimal.new("13345.234").floor(-2))
876  end
877
878  def test_ceil
879    assert_equal(4, BigDecimal.new("3.14159").ceil)
880    assert_equal(-9, BigDecimal.new("-9.1").ceil)
881    assert_equal(3.142, BigDecimal.new("3.14159").ceil(3))
882    assert_equal(13400.0, BigDecimal.new("13345.234").ceil(-2))
883  end
884
885  def test_to_s
886    assert_equal('-123.45678 90123 45678 9', BigDecimal.new('-123.45678901234567890').to_s('5F'))
887    assert_equal('+123.45678901 23456789', BigDecimal.new('123.45678901234567890').to_s('+8F'))
888    assert_equal(' 123.4567890123456789', BigDecimal.new('123.45678901234567890').to_s(' F'))
889    assert_equal('0.1234567890123456789E3', BigDecimal.new('123.45678901234567890').to_s)
890    assert_equal('0.12345 67890 12345 6789E3', BigDecimal.new('123.45678901234567890').to_s(5))
891  end
892
893  def test_split
894    x = BigDecimal.new('-123.45678901234567890')
895    assert_equal([-1, "1234567890123456789", 10, 3], x.split)
896    assert_equal([1, "0", 10, 0], BigDecimal.new("0").split)
897    assert_equal([-1, "0", 10, 0], BigDecimal.new("-0").split)
898
899    BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
900    BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
901    assert_equal([0, "NaN", 10, 0], BigDecimal.new("NaN").split)
902    assert_equal([1, "Infinity", 10, 0], BigDecimal.new("Infinity").split)
903    assert_equal([-1, "Infinity", 10, 0], BigDecimal.new("-Infinity").split)
904  end
905
906  def test_exponent
907    x = BigDecimal.new('-123.45678901234567890')
908    assert_equal(3, x.exponent)
909  end
910
911  def test_inspect
912    x = BigDecimal.new("1234.5678")
913    prec, maxprec = x.precs
914    assert_match(/^#<BigDecimal:[0-9a-f]+,'0.12345678E4',#{prec}\(#{maxprec}\)>$/, x.inspect)
915  end
916
917  def test_power
918    assert_nothing_raised(TypeError, '[ruby-core:47632]') do
919      1000.times { BigDecimal.new('1001.10')**0.75 }
920    end
921  end
922
923  def test_power_with_nil
924    assert_raise(TypeError) do
925      BigDecimal(3) ** nil
926    end
927  end
928
929  def test_power_of_nan
930    BigDecimal.save_exception_mode do
931      BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
932      assert_nan(BigDecimal::NAN ** 0)
933      assert_nan(BigDecimal::NAN ** 1)
934      assert_nan(BigDecimal::NAN ** 42)
935      assert_nan(BigDecimal::NAN ** -42)
936      assert_nan(BigDecimal::NAN ** 42.0)
937      assert_nan(BigDecimal::NAN ** -42.0)
938      assert_nan(BigDecimal::NAN ** BigDecimal(42))
939      assert_nan(BigDecimal::NAN ** BigDecimal(-42))
940      assert_nan(BigDecimal::NAN ** BigDecimal::INFINITY)
941      BigDecimal.save_exception_mode do
942        BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
943        assert_nan(BigDecimal::NAN ** (-BigDecimal::INFINITY))
944      end
945    end
946  end
947
948  def test_power_with_Bignum
949    BigDecimal.save_exception_mode do
950      BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
951      assert_equal(0, BigDecimal(0) ** (2**100))
952
953      assert_positive_infinite(BigDecimal(0) ** -(2**100))
954      assert_positive_infinite((-BigDecimal(0)) ** -(2**100))
955      assert_negative_infinite((-BigDecimal(0)) ** -(2**100 + 1))
956
957      assert_equal(1, BigDecimal(1) ** (2**100))
958
959      assert_positive_infinite(BigDecimal(3) ** (2**100))
960      assert_positive_zero(BigDecimal(3) ** (-2**100))
961
962      assert_negative_infinite(BigDecimal(-3) ** (2**100))
963      assert_positive_infinite(BigDecimal(-3) ** (2**100 + 1))
964      assert_negative_zero(BigDecimal(-3) ** (-2**100))
965      assert_positive_zero(BigDecimal(-3) ** (-2**100 - 1))
966
967      assert_positive_zero(BigDecimal(0.5, Float::DIG) ** (2**100))
968      assert_positive_infinite(BigDecimal(0.5, Float::DIG) ** (-2**100))
969
970      assert_negative_zero(BigDecimal(-0.5, Float::DIG) ** (2**100))
971      assert_positive_zero(BigDecimal(-0.5, Float::DIG) ** (2**100 - 1))
972      assert_negative_infinite(BigDecimal(-0.5, Float::DIG) ** (-2**100))
973      assert_positive_infinite(BigDecimal(-0.5, Float::DIG) ** (-2**100 - 1))
974    end
975  end
976
977  def test_power_with_BigDecimal
978    assert_nothing_raised do
979      assert_in_delta(3 ** 3, BigDecimal(3) ** BigDecimal(3))
980    end
981  end
982
983  def test_power_of_finite_with_zero
984    x = BigDecimal(1)
985    assert_equal(1, x ** 0)
986    assert_equal(1, x ** 0.quo(1))
987    assert_equal(1, x ** 0.0)
988    assert_equal(1, x ** BigDecimal(0))
989
990    x = BigDecimal(42)
991    assert_equal(1, x ** 0)
992    assert_equal(1, x ** 0.quo(1))
993    assert_equal(1, x ** 0.0)
994    assert_equal(1, x ** BigDecimal(0))
995
996    x = BigDecimal(-42)
997    assert_equal(1, x ** 0)
998    assert_equal(1, x ** 0.quo(1))
999    assert_equal(1, x ** 0.0)
1000    assert_equal(1, x ** BigDecimal(0))
1001  end
1002
1003  def test_power_of_three
1004    x = BigDecimal(3)
1005    assert_equal(81, x ** 4)
1006    assert_equal(1.quo(81), x ** -4)
1007    assert_in_delta(1.0/81, x ** -4)
1008  end
1009
1010  def test_power_of_zero
1011    zero = BigDecimal(0)
1012    assert_equal(0, zero ** 4)
1013    assert_equal(0, zero ** 4.quo(1))
1014    assert_equal(0, zero ** 4.0)
1015    assert_equal(0, zero ** BigDecimal(4))
1016    assert_equal(1, zero ** 0)
1017    assert_equal(1, zero ** 0.quo(1))
1018    assert_equal(1, zero ** 0.0)
1019    assert_equal(1, zero ** BigDecimal(0))
1020    BigDecimal.save_exception_mode do
1021      BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
1022      BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
1023      assert_positive_infinite(zero ** -1)
1024      assert_positive_infinite(zero ** -1.quo(1))
1025      assert_positive_infinite(zero ** -1.0)
1026      assert_positive_infinite(zero ** BigDecimal(-1))
1027
1028      m_zero = BigDecimal("-0")
1029      assert_negative_infinite(m_zero ** -1)
1030      assert_negative_infinite(m_zero ** -1.quo(1))
1031      assert_negative_infinite(m_zero ** -1.0)
1032      assert_negative_infinite(m_zero ** BigDecimal(-1))
1033      assert_positive_infinite(m_zero ** -2)
1034      assert_positive_infinite(m_zero ** -2.quo(1))
1035      assert_positive_infinite(m_zero ** -2.0)
1036      assert_positive_infinite(m_zero ** BigDecimal(-2))
1037    end
1038  end
1039
1040  def test_power_of_positive_infinity
1041    BigDecimal.save_exception_mode do
1042      BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
1043      assert_positive_infinite(BigDecimal::INFINITY ** 3)
1044      assert_positive_infinite(BigDecimal::INFINITY ** 3.quo(1))
1045      assert_positive_infinite(BigDecimal::INFINITY ** 3.0)
1046      assert_positive_infinite(BigDecimal::INFINITY ** BigDecimal(3))
1047      assert_positive_infinite(BigDecimal::INFINITY ** 2)
1048      assert_positive_infinite(BigDecimal::INFINITY ** 2.quo(1))
1049      assert_positive_infinite(BigDecimal::INFINITY ** 2.0)
1050      assert_positive_infinite(BigDecimal::INFINITY ** BigDecimal(2))
1051      assert_positive_infinite(BigDecimal::INFINITY ** 1)
1052      assert_positive_infinite(BigDecimal::INFINITY ** 1.quo(1))
1053      assert_positive_infinite(BigDecimal::INFINITY ** 1.0)
1054      assert_positive_infinite(BigDecimal::INFINITY ** BigDecimal(1))
1055      assert_equal(1, BigDecimal::INFINITY ** 0)
1056      assert_equal(1, BigDecimal::INFINITY ** 0.quo(1))
1057      assert_equal(1, BigDecimal::INFINITY ** 0.0)
1058      assert_equal(1, BigDecimal::INFINITY ** BigDecimal(0))
1059      assert_positive_zero(BigDecimal::INFINITY ** -1)
1060      assert_positive_zero(BigDecimal::INFINITY ** -1.quo(1))
1061      assert_positive_zero(BigDecimal::INFINITY ** -1.0)
1062      assert_positive_zero(BigDecimal::INFINITY ** BigDecimal(-1))
1063      assert_positive_zero(BigDecimal::INFINITY ** -2)
1064      assert_positive_zero(BigDecimal::INFINITY ** -2.0)
1065      assert_positive_zero(BigDecimal::INFINITY ** BigDecimal(-2))
1066    end
1067  end
1068
1069  def test_power_of_negative_infinity
1070    BigDecimal.save_exception_mode do
1071      BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
1072      assert_negative_infinite((-BigDecimal::INFINITY) ** 3)
1073      assert_negative_infinite((-BigDecimal::INFINITY) ** 3.quo(1))
1074      assert_negative_infinite((-BigDecimal::INFINITY) ** 3.0)
1075      assert_negative_infinite((-BigDecimal::INFINITY) ** BigDecimal(3))
1076      assert_positive_infinite((-BigDecimal::INFINITY) ** 2)
1077      assert_positive_infinite((-BigDecimal::INFINITY) ** 2.quo(1))
1078      assert_positive_infinite((-BigDecimal::INFINITY) ** 2.0)
1079      assert_positive_infinite((-BigDecimal::INFINITY) ** BigDecimal(2))
1080      assert_negative_infinite((-BigDecimal::INFINITY) ** 1)
1081      assert_negative_infinite((-BigDecimal::INFINITY) ** 1.quo(1))
1082      assert_negative_infinite((-BigDecimal::INFINITY) ** 1.0)
1083      assert_negative_infinite((-BigDecimal::INFINITY) ** BigDecimal(1))
1084      assert_equal(1, (-BigDecimal::INFINITY) ** 0)
1085      assert_equal(1, (-BigDecimal::INFINITY) ** 0.quo(1))
1086      assert_equal(1, (-BigDecimal::INFINITY) ** 0.0)
1087      assert_equal(1, (-BigDecimal::INFINITY) ** BigDecimal(0))
1088      assert_negative_zero((-BigDecimal::INFINITY) ** -1)
1089      assert_negative_zero((-BigDecimal::INFINITY) ** -1.quo(1))
1090      assert_negative_zero((-BigDecimal::INFINITY) ** -1.0)
1091      assert_negative_zero((-BigDecimal::INFINITY) ** BigDecimal(-1))
1092      assert_positive_zero((-BigDecimal::INFINITY) ** -2)
1093      assert_positive_zero((-BigDecimal::INFINITY) ** -2.quo(1))
1094      assert_positive_zero((-BigDecimal::INFINITY) ** -2.0)
1095      assert_positive_zero((-BigDecimal::INFINITY) ** BigDecimal(-2))
1096    end
1097  end
1098
1099  def test_power_without_prec
1100    pi  = BigDecimal("3.14159265358979323846264338327950288419716939937511")
1101    e   = BigDecimal("2.71828182845904523536028747135266249775724709369996")
1102    pow = BigDecimal("22.4591577183610454734271522045437350275893151339967843873233068")
1103    assert_equal(pow, pi.power(e))
1104  end
1105
1106  def test_power_with_prec
1107    pi  = BigDecimal("3.14159265358979323846264338327950288419716939937511")
1108    e   = BigDecimal("2.71828182845904523536028747135266249775724709369996")
1109    pow = BigDecimal("22.459157718361045473")
1110    assert_equal(pow, pi.power(e, 20))
1111  end
1112
1113  def test_limit
1114    BigDecimal.limit(1)
1115    x = BigDecimal.new("3")
1116    assert_equal(90, x ** 4) # OK? must it be 80?
1117    # 3 * 3 * 3 * 3 = 10 * 3 * 3 = 30 * 3 = 90 ???
1118    assert_raise(ArgumentError) { BigDecimal.limit(-1) }
1119  end
1120
1121  def test_sign
1122    BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
1123    BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
1124    BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false)
1125
1126    assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, BigDecimal.new("0").sign)
1127    assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, BigDecimal.new("-0").sign)
1128    assert_equal(BigDecimal::SIGN_POSITIVE_FINITE, BigDecimal.new("1").sign)
1129    assert_equal(BigDecimal::SIGN_NEGATIVE_FINITE, BigDecimal.new("-1").sign)
1130    assert_equal(BigDecimal::SIGN_POSITIVE_INFINITE, (BigDecimal.new("1") / 0).sign)
1131    assert_equal(BigDecimal::SIGN_NEGATIVE_INFINITE, (BigDecimal.new("-1") / 0).sign)
1132    assert_equal(BigDecimal::SIGN_NaN, (BigDecimal.new("0") / 0).sign)
1133  end
1134
1135  def test_inf
1136    BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
1137    BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
1138    inf = BigDecimal.new("Infinity")
1139
1140    assert_equal(inf, inf + inf)
1141    assert_equal(true, (inf + (-inf)).nan?)
1142    assert_equal(true, (inf - inf).nan?)
1143    assert_equal(inf, inf - (-inf))
1144    assert_equal(inf, inf * inf)
1145    assert_equal(true, (inf / inf).nan?)
1146
1147    assert_equal(inf, inf + 1)
1148    assert_equal(inf, inf - 1)
1149    assert_equal(inf, inf * 1)
1150    assert_equal(true, (inf * 0).nan?)
1151    assert_equal(inf, inf / 1)
1152
1153    assert_equal(inf, 1 + inf)
1154    assert_equal(-inf, 1 - inf)
1155    assert_equal(inf, 1 * inf)
1156    assert_equal(-inf, -1 * inf)
1157    assert_equal(true, (0 * inf).nan?)
1158    assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (1 / inf).sign)
1159    assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (-1 / inf).sign)
1160  end
1161
1162  def test_to_special_string
1163    BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
1164    BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
1165    nan = BigDecimal.new("NaN")
1166    assert_equal("NaN", nan.to_s)
1167    inf = BigDecimal.new("Infinity")
1168    assert_equal("Infinity", inf.to_s)
1169    assert_equal(" Infinity", inf.to_s(" "))
1170    assert_equal("+Infinity", inf.to_s("+"))
1171    assert_equal("-Infinity", (-inf).to_s)
1172    pzero = BigDecimal.new("0")
1173    assert_equal("0.0", pzero.to_s)
1174    assert_equal(" 0.0", pzero.to_s(" "))
1175    assert_equal("+0.0", pzero.to_s("+"))
1176    assert_equal("-0.0", (-pzero).to_s)
1177  end
1178
1179  def test_to_string
1180    assert_equal("0.01", BigDecimal("0.01").to_s("F"))
1181    s = "0." + "0" * 100 + "1"
1182    assert_equal(s, BigDecimal(s).to_s("F"))
1183    s = "1" + "0" * 100 + ".0"
1184    assert_equal(s, BigDecimal(s).to_s("F"))
1185  end
1186
1187  def test_ctov
1188    assert_equal(0.1, BigDecimal.new("1E-1"))
1189    assert_equal(10, BigDecimal.new("1E+1"))
1190    assert_equal(1, BigDecimal.new("+1"))
1191    BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
1192
1193    assert_equal(BigDecimal::SIGN_POSITIVE_INFINITE, BigDecimal.new("1E1" + "0" * 10000).sign)
1194    assert_equal(BigDecimal::SIGN_NEGATIVE_INFINITE, BigDecimal.new("-1E1" + "0" * 10000).sign)
1195    assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, BigDecimal.new("1E-1" + "0" * 10000).sign)
1196    assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, BigDecimal.new("-1E-1" + "0" * 10000).sign)
1197  end
1198
1199  def test_split_under_gc_stress
1200    bug3258 = '[ruby-dev:41213]'
1201    expect = 10.upto(20).map{|i|[1, "1", 10, i+1].inspect}
1202    assert_in_out_err(%w[-rbigdecimal --disable-gems], <<-EOS, expect, [], bug3258)
1203    GC.stress = true
1204    10.upto(20) do |i|
1205      p BigDecimal.new("1"+"0"*i).split
1206    end
1207    EOS
1208  end
1209
1210  def test_coerce_under_gc_stress
1211    assert_in_out_err(%w[-rbigdecimal --disable-gems], <<-EOS, [], [])
1212      expect = ":too_long_to_embed_as_string can't be coerced into BigDecimal"
1213      b = BigDecimal.new("1")
1214      GC.stress = true
1215      10.times do
1216        begin
1217          b.coerce(:too_long_to_embed_as_string)
1218        rescue => e
1219          raise unless e.is_a?(TypeError)
1220          raise "'\#{expect}' is expected, but '\#{e.message}'" unless e.message == expect
1221        end
1222      end
1223    EOS
1224  end
1225
1226  def test_INFINITY
1227    assert(BigDecimal::INFINITY.infinite?, "BigDecimal::INFINITY is not a infinity")
1228  end
1229
1230  def test_NAN
1231    assert(BigDecimal::NAN.nan?, "BigDecimal::NAN is not NaN")
1232  end
1233
1234  def test_exp_with_zerp_precision
1235    assert_raise(ArgumentError) do
1236      BigMath.exp(1, 0)
1237    end
1238  end
1239
1240  def test_exp_with_negative_precision
1241    assert_raise(ArgumentError) do
1242      BigMath.exp(1, -42)
1243    end
1244  end
1245
1246  def test_exp_with_complex
1247    assert_raise(ArgumentError) do
1248      BigMath.exp(Complex(1, 2), 20)
1249    end
1250  end
1251
1252  def test_exp_with_negative_infinite
1253    BigDecimal.save_exception_mode do
1254      BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
1255      assert_equal(0, BigMath.exp(-BigDecimal::INFINITY, 20))
1256    end
1257  end
1258
1259  def test_exp_with_positive_infinite
1260    BigDecimal.save_exception_mode do
1261      BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
1262      assert(BigMath.exp(BigDecimal::INFINITY, 20) > 0)
1263      assert(BigMath.exp(BigDecimal::INFINITY, 20).infinite?)
1264    end
1265  end
1266
1267  def test_exp_with_nan
1268    BigDecimal.save_exception_mode do
1269      BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
1270      assert(BigMath.exp(BigDecimal::NAN, 20).nan?)
1271    end
1272  end
1273
1274  def test_exp_with_1
1275    assert_in_epsilon(Math::E, BigMath.exp(1, 20))
1276  end
1277
1278  def test_BigMath_exp
1279    prec = 20
1280    assert_in_epsilon(Math.exp(20), BigMath.exp(BigDecimal("20"), prec))
1281    assert_in_epsilon(Math.exp(40), BigMath.exp(BigDecimal("40"), prec))
1282    assert_in_epsilon(Math.exp(-20), BigMath.exp(BigDecimal("-20"), prec))
1283    assert_in_epsilon(Math.exp(-40), BigMath.exp(BigDecimal("-40"), prec))
1284  end
1285
1286  def test_BigMath_exp_with_float
1287    prec = 20
1288    assert_in_epsilon(Math.exp(20), BigMath.exp(20.0, prec))
1289    assert_in_epsilon(Math.exp(40), BigMath.exp(40.0, prec))
1290    assert_in_epsilon(Math.exp(-20), BigMath.exp(-20.0, prec))
1291    assert_in_epsilon(Math.exp(-40), BigMath.exp(-40.0, prec))
1292  end
1293
1294  def test_BigMath_exp_with_fixnum
1295    prec = 20
1296    assert_in_epsilon(Math.exp(20), BigMath.exp(20, prec))
1297    assert_in_epsilon(Math.exp(40), BigMath.exp(40, prec))
1298    assert_in_epsilon(Math.exp(-20), BigMath.exp(-20, prec))
1299    assert_in_epsilon(Math.exp(-40), BigMath.exp(-40, prec))
1300  end
1301
1302  def test_BigMath_exp_with_rational
1303    prec = 20
1304    assert_in_epsilon(Math.exp(20), BigMath.exp(Rational(40,2), prec))
1305    assert_in_epsilon(Math.exp(40), BigMath.exp(Rational(80,2), prec))
1306    assert_in_epsilon(Math.exp(-20), BigMath.exp(Rational(-40,2), prec))
1307    assert_in_epsilon(Math.exp(-40), BigMath.exp(Rational(-80,2), prec))
1308  end
1309
1310  def test_BigMath_exp_under_gc_stress
1311    assert_in_out_err(%w[-rbigdecimal --disable-gems], <<-EOS, [], [])
1312      expect = ":too_long_to_embed_as_string can't be coerced into BigDecimal"
1313      10.times do
1314        begin
1315          BigMath.exp(:too_long_to_embed_as_string, 6)
1316        rescue => e
1317          raise unless e.is_a?(ArgumentError)
1318          raise "'\#{expect}' is expected, but '\#{e.message}'" unless e.message == expect
1319        end
1320      end
1321    EOS
1322  end
1323
1324  def test_BigMath_log_with_nil
1325    assert_raise(ArgumentError) do
1326      BigMath.log(nil, 20)
1327    end
1328  end
1329
1330  def test_BigMath_log_with_nil_precision
1331    assert_raise(ArgumentError) do
1332      BigMath.log(1, nil)
1333    end
1334  end
1335
1336  def test_BigMath_log_with_complex
1337    assert_raise(Math::DomainError) do
1338      BigMath.log(Complex(1, 2), 20)
1339    end
1340  end
1341
1342  def test_BigMath_log_with_zerp_precision
1343    assert_raise(ArgumentError) do
1344      BigMath.log(1, 0)
1345    end
1346  end
1347
1348  def test_BigMath_log_with_negative_precision
1349    assert_raise(ArgumentError) do
1350      BigMath.log(1, -42)
1351    end
1352  end
1353
1354  def test_BigMath_log_with_negative_infinite
1355    BigDecimal.save_exception_mode do
1356      BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
1357      assert_raise(Math::DomainError) do
1358        BigMath.log(-BigDecimal::INFINITY, 20)
1359      end
1360    end
1361  end
1362
1363  def test_BigMath_log_with_positive_infinite
1364    BigDecimal.save_exception_mode do
1365      BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
1366      assert(BigMath.log(BigDecimal::INFINITY, 20) > 0)
1367      assert(BigMath.log(BigDecimal::INFINITY, 20).infinite?)
1368    end
1369  end
1370
1371  def test_BigMath_log_with_nan
1372    BigDecimal.save_exception_mode do
1373      BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
1374      assert(BigMath.log(BigDecimal::NAN, 20).nan?)
1375    end
1376  end
1377
1378  def test_BigMath_log_with_1
1379    assert_in_delta(0.0, BigMath.log(1, 20))
1380    assert_in_delta(0.0, BigMath.log(1.0, 20))
1381    assert_in_delta(0.0, BigMath.log(BigDecimal(1), 20))
1382  end
1383
1384  def test_BigMath_log_with_exp_1
1385    assert_in_delta(1.0, BigMath.log(BigMath.exp(1, 20), 20))
1386  end
1387
1388  def test_BigMath_log_with_2
1389    assert_in_delta(Math.log(2), BigMath.log(2, 20))
1390    assert_in_delta(Math.log(2), BigMath.log(2.0, 20))
1391    assert_in_delta(Math.log(2), BigMath.log(BigDecimal(2), 20))
1392  end
1393
1394  def test_BigMath_log_with_square_of_exp_2
1395    assert_in_delta(2, BigMath.log(BigMath.exp(1, 20)**2, 20))
1396  end
1397
1398  def test_BigMath_log_with_42
1399    assert_in_delta(Math.log(42), BigMath.log(42, 20))
1400    assert_in_delta(Math.log(42), BigMath.log(42.0, 20))
1401    assert_in_delta(Math.log(42), BigMath.log(BigDecimal(42), 20))
1402  end
1403
1404  def test_BigMath_log_with_reciprocal_of_42
1405    assert_in_delta(Math.log(1e-42), BigMath.log(1e-42, 20))
1406    assert_in_delta(Math.log(1e-42), BigMath.log(BigDecimal("1e-42"), 20))
1407  end
1408
1409  def test_BigMath_log_under_gc_stress
1410    assert_in_out_err(%w[-rbigdecimal --disable-gems], <<-EOS, [], [])
1411      expect = ":too_long_to_embed_as_string can't be coerced into BigDecimal"
1412      10.times do
1413        begin
1414          BigMath.log(:too_long_to_embed_as_string, 6)
1415        rescue => e
1416          raise unless e.is_a?(ArgumentError)
1417          raise "'\#{expect}' is expected, but '\#{e.message}'" unless e.message == expect
1418        end
1419      end
1420    EOS
1421  end
1422
1423  def test_dup
1424    [1, -1, 2**100, -2**100].each do |i|
1425      x = BigDecimal(i)
1426      assert_equal(x, x.dup)
1427    end
1428  end
1429
1430  def test_dup_subclass
1431    c = Class.new(BigDecimal)
1432    x = c.new(1)
1433    y = x.dup
1434    assert_equal(1, y)
1435    assert_kind_of(c, y)
1436  end
1437
1438  def test_to_d
1439    bug6093 = '[ruby-core:42969]'
1440    code = "exit(BigDecimal.new('10.0') == 10.0.to_d)"
1441    assert_ruby_status(%w[-rbigdecimal -rbigdecimal/util -rmathn -], code, bug6093)
1442  end
1443
1444  def test_bug6406
1445    assert_in_out_err(%w[-rbigdecimal --disable-gems], <<-EOS, [], [])
1446    Thread.current.keys.to_s
1447    EOS
1448  end
1449end
1450