1# frozen_string_literal: false
2require 'test/unit'
3
4class ComplexSub < Complex; end
5
6class Complex_Test < Test::Unit::TestCase
7
8  def test_rationalize
9    assert_equal(1.quo(3), Complex(1/3.0, 0).rationalize, '[ruby-core:38885]')
10    assert_equal(1.quo(5), Complex(0.2, 0).rationalize, '[ruby-core:38885]')
11    assert_equal(5.quo(2), Complex(2.5, 0).rationalize(0), '[ruby-core:40667]')
12  end
13
14  def test_compsub
15    c = ComplexSub.__send__(:convert, 1)
16
17    assert_kind_of(Numeric, c)
18
19    assert_instance_of(ComplexSub, c)
20
21    c2 = c + 1
22    assert_instance_of(ComplexSub, c2)
23    c2 = c - 1
24    assert_instance_of(ComplexSub, c2)
25
26    c3 = c - c2
27    assert_instance_of(ComplexSub, c3)
28
29    s = Marshal.dump(c)
30    c5 = Marshal.load(s)
31    assert_equal(c, c5)
32    assert_instance_of(ComplexSub, c5)
33
34    c1 = Complex(1)
35    assert_equal(c1.hash, c.hash, '[ruby-dev:38850]')
36    assert_equal([true, true], [c.eql?(c1), c1.eql?(c)])
37  end
38
39  def test_eql_p
40    c = Complex(0)
41    c2 = Complex(0)
42    c3 = Complex(1)
43
44    assert_operator(c, :eql?, c2)
45    assert_not_operator(c, :eql?, c3)
46
47    assert_not_operator(c, :eql?, 0)
48  end
49
50  def test_hash
51    h = Complex(1,2).hash
52    assert_kind_of(Integer, h)
53    assert_nothing_raised {h.to_s}
54    h = Complex(1.0,2.0).hash
55    assert_kind_of(Integer, h)
56    assert_nothing_raised {h.to_s}
57
58    h = {}
59    h[Complex(0)] = 0
60    h[Complex(0,1)] = 1
61    h[Complex(1,0)] = 2
62    h[Complex(1,1)] = 3
63
64    assert_equal(4, h.size)
65    assert_equal(2, h[Complex(1,0)])
66
67    h[Complex(0,0)] = 9
68    assert_equal(4, h.size)
69
70    h[Complex(0.0,0.0)] = 9.0
71    assert_equal(5, h.size)
72
73    if (0.0/0).nan? && !((0.0/0).eql?(0.0/0))
74      h = {}
75      3.times{h[Complex(0.0/0)] = 1}
76      assert_equal(3, h.size)
77    end
78  end
79
80  def test_freeze
81    c = Complex(1)
82    assert_predicate(c, :frozen?)
83    assert_instance_of(String, c.to_s)
84  end
85
86  def test_conv
87    c = Complex(0,0)
88    assert_equal(Complex(0,0), c)
89
90    c = Complex(2**32, 2**32)
91    assert_equal(Complex(2**32,2**32), c)
92    assert_equal([2**32,2**32], [c.real,c.imag])
93
94    c = Complex(-2**32, 2**32)
95    assert_equal(Complex(-2**32,2**32), c)
96    assert_equal([-2**32,2**32], [c.real,c.imag])
97
98    c = Complex(2**32, -2**32)
99    assert_equal(Complex(2**32,-2**32), c)
100    assert_equal([2**32,-2**32], [c.real,c.imag])
101
102    c = Complex(-2**32, -2**32)
103    assert_equal(Complex(-2**32,-2**32), c)
104    assert_equal([-2**32,-2**32], [c.real,c.imag])
105
106    c = Complex(Complex(1,2),2)
107    assert_equal(Complex(1,4), c)
108
109    c = Complex(2,Complex(1,2))
110    assert_equal(Complex(0,1), c)
111
112    c = Complex(Complex(1,2),Complex(1,2))
113    assert_equal(Complex(-1,3), c)
114
115    c = Complex::I
116    assert_equal(Complex(0,1), c)
117
118    assert_equal(Complex(1),Complex(1))
119    assert_equal(Complex(1),Complex('1'))
120    assert_equal(Complex(3.0,3.0),Complex('3.0','3.0'))
121    assert_equal(Complex(1,1),Complex('3/3','3/3'))
122    assert_raise(TypeError){Complex(nil)}
123    assert_raise(TypeError){Complex(Object.new)}
124    assert_raise(ArgumentError){Complex()}
125    assert_raise(ArgumentError){Complex(1,2,3)}
126
127    if (0.0/0).nan?
128      assert_nothing_raised{Complex(0.0/0)}
129    end
130    if (1.0/0).infinite?
131      assert_nothing_raised{Complex(1.0/0)}
132    end
133  end
134
135  def test_attr
136    c = Complex(4)
137
138    assert_equal(4, c.real)
139    assert_equal(0, c.imag)
140
141    c = Complex(4,5)
142
143    assert_equal(4, c.real)
144    assert_equal(5, c.imag)
145
146    if -0.0.to_s == '-0.0'
147      c = Complex(-0.0,-0.0)
148
149      assert_equal('-0.0', c.real.to_s)
150      assert_equal('-0.0', c.imag.to_s)
151    end
152
153    c = Complex(4)
154
155    assert_equal(4, c.real)
156    assert_equal(0, c.imag)
157    assert_equal(c.imag, c.imaginary)
158
159    c = Complex(4,5)
160
161    assert_equal(4, c.real)
162    assert_equal(5, c.imag)
163    assert_equal(c.imag, c.imaginary)
164
165    if -0.0.to_s == '-0.0'
166      c = Complex(-0.0,-0.0)
167
168      assert_equal('-0.0', c.real.to_s)
169      assert_equal('-0.0', c.imag.to_s)
170      assert_equal(c.imag.to_s, c.imaginary.to_s)
171    end
172
173    c = Complex(4)
174
175    assert_equal(4, c.real)
176    assert_equal(c.imag, c.imaginary)
177    assert_equal(0, c.imag)
178
179    c = Complex(4,5)
180
181    assert_equal(4, c.real)
182    assert_equal(5, c.imag)
183    assert_equal(c.imag, c.imaginary)
184
185    c = Complex(-0.0,-0.0)
186
187    assert_equal('-0.0', c.real.to_s)
188    assert_equal('-0.0', c.imag.to_s)
189    assert_equal(c.imag.to_s, c.imaginary.to_s)
190  end
191
192  def test_attr2
193    c = Complex(1)
194
195    assert_not_predicate(c, :integer?)
196    assert_not_predicate(c, :real?)
197
198    assert_predicate(Complex(0), :zero?)
199    assert_predicate(Complex(0,0), :zero?)
200    assert_not_predicate(Complex(1,0), :zero?)
201    assert_not_predicate(Complex(0,1), :zero?)
202    assert_not_predicate(Complex(1,1), :zero?)
203
204    assert_equal(nil, Complex(0).nonzero?)
205    assert_equal(nil, Complex(0,0).nonzero?)
206    assert_equal(Complex(1,0), Complex(1,0).nonzero?)
207    assert_equal(Complex(0,1), Complex(0,1).nonzero?)
208    assert_equal(Complex(1,1), Complex(1,1).nonzero?)
209  end
210
211  def test_rect
212    assert_equal([1,2], Complex.rectangular(1,2).rectangular)
213    assert_equal([1,2], Complex.rect(1,2).rect)
214  end
215
216  def test_polar
217    assert_equal([1,2], Complex.polar(1,2).polar)
218    assert_equal(Complex.polar(1.0, Math::PI * 2 / 3), Complex.polar(1, Math::PI * 2 / 3))
219  end
220
221  def test_uplus
222    assert_equal(Complex(1), +Complex(1))
223    assert_equal(Complex(-1), +Complex(-1))
224    assert_equal(Complex(1,1), +Complex(1,1))
225    assert_equal(Complex(-1,1), +Complex(-1,1))
226    assert_equal(Complex(1,-1), +Complex(1,-1))
227    assert_equal(Complex(-1,-1), +Complex(-1,-1))
228
229    if -0.0.to_s == '-0.0'
230      c = +Complex(0.0,0.0)
231      assert_equal('0.0', c.real.to_s)
232      assert_equal('0.0', c.imag.to_s)
233
234      c = +Complex(-0.0,-0.0)
235      assert_equal('-0.0', c.real.to_s)
236      assert_equal('-0.0', c.imag.to_s)
237    end
238  end
239
240  def test_negate
241    assert_equal(Complex(-1), -Complex(1))
242    assert_equal(Complex(1), -Complex(-1))
243    assert_equal(Complex(-1,-1), -Complex(1,1))
244    assert_equal(Complex(1,-1), -Complex(-1,1))
245    assert_equal(Complex(-1,1), -Complex(1,-1))
246    assert_equal(Complex(1,1), -Complex(-1,-1))
247
248    if -0.0.to_s == '-0.0'
249      c = -Complex(0.0,0.0)
250      assert_equal('-0.0', c.real.to_s)
251      assert_equal('-0.0', c.imag.to_s)
252
253      c = -Complex(-0.0,-0.0)
254      assert_equal('0.0', c.real.to_s)
255      assert_equal('0.0', c.imag.to_s)
256    end
257  end
258
259  def test_add
260    c = Complex(1,2)
261    c2 = Complex(2,3)
262
263    assert_equal(Complex(3,5), c + c2)
264
265    assert_equal(Complex(3,2), c + 2)
266    assert_equal(Complex(3.0,2), c + 2.0)
267
268    assert_equal(Complex(Rational(3,1),Rational(2)), c + Rational(2))
269    assert_equal(Complex(Rational(5,3),Rational(2)), c + Rational(2,3))
270  end
271
272  def test_add_with_redefining_int_plus
273    assert_in_out_err([], <<-'end;', ['true'], [])
274      class Integer
275        remove_method :+
276        def +(other); 42; end
277      end
278      a = Complex(1, 2) + Complex(0, 1)
279      puts a == Complex(42, 42)
280    end;
281  end
282
283  def test_add_with_redefining_float_plus
284    assert_in_out_err([], <<-'end;', ['true'], [])
285      class Float
286        remove_method :+
287        def +(other); 42.0; end
288      end
289      a = Complex(1.0, 2.0) + Complex(0, 1)
290      puts a == Complex(42.0, 42.0)
291    end;
292  end
293
294  def test_add_with_redefining_rational_plus
295    assert_in_out_err([], <<-'end;', ['true'], [])
296      class Rational
297        remove_method :+
298        def +(other); 355/113r; end
299      end
300      a = Complex(1r, 2r) + Complex(0, 1)
301      puts a == Complex(355/113r, 355/113r)
302    end;
303  end
304
305  def test_sub
306    c = Complex(1,2)
307    c2 = Complex(2,3)
308
309    assert_equal(Complex(-1,-1), c - c2)
310
311    assert_equal(Complex(-1,2), c - 2)
312    assert_equal(Complex(-1.0,2), c - 2.0)
313
314    assert_equal(Complex(Rational(-1,1),Rational(2)), c - Rational(2))
315    assert_equal(Complex(Rational(1,3),Rational(2)), c - Rational(2,3))
316  end
317
318  def test_sub_with_redefining_int_minus
319    assert_in_out_err([], <<-'end;', ['true'], [])
320      class Integer
321        remove_method :-
322        def -(other); 42; end
323      end
324      a = Complex(1, 2) - Complex(0, 1)
325      puts a == Complex(42, 42)
326    end;
327  end
328
329  def test_sub_with_redefining_float_minus
330    assert_in_out_err([], <<-'end;', ['true'], [])
331      class Float
332        remove_method :-
333        def -(other); 42.0; end
334      end
335      a = Complex(1.0, 2.0) - Complex(0, 1)
336      puts a == Complex(42.0, 42.0)
337    end;
338  end
339
340  def test_sub_with_redefining_rational_minus
341    assert_in_out_err([], <<-'end;', ['true'], [])
342      class Rational
343        remove_method :-
344        def -(other); 355/113r; end
345      end
346      a = Complex(1r, 2r) - Complex(0, 1)
347      puts a == Complex(355/113r, 355/113r)
348    end;
349  end
350
351  def test_mul
352    c = Complex(1,2)
353    c2 = Complex(2,3)
354
355    assert_equal(Complex(-4,7), c * c2)
356
357    assert_equal(Complex(2,4), c * 2)
358    assert_equal(Complex(2.0,4.0), c * 2.0)
359
360    assert_equal(Complex(Rational(2,1),Rational(4)), c * Rational(2))
361    assert_equal(Complex(Rational(2,3),Rational(4,3)), c * Rational(2,3))
362
363    c = Complex(Float::INFINITY, 0)
364    assert_equal(Complex(Float::INFINITY, 0), c * Complex(1, 0))
365    assert_equal(Complex(0, Float::INFINITY), c * Complex(0, 1))
366    c = Complex(0, Float::INFINITY)
367    assert_equal(Complex(0, Float::INFINITY), c * Complex(1, 0))
368    assert_equal(Complex(-Float::INFINITY, 0), c * Complex(0, 1))
369
370    assert_equal(Complex(-0.0, -0.0), Complex(-0.0, 0) * Complex(0, 0))
371  end
372
373  def test_mul_with_redefining_int_mult
374    assert_in_out_err([], <<-'end;', ['true'], [])
375      class Integer
376        remove_method :*
377        def *(other); 42; end
378      end
379      a = Complex(2, 0) * Complex(1, 2)
380      puts a == Complex(0, 84)
381    end;
382  end
383
384  def test_mul_with_redefining_float_mult
385    assert_in_out_err([], <<-'end;', ['true'], [])
386      class Float
387        remove_method :*
388        def *(other); 42.0; end
389      end
390      a = Complex(2.0, 0.0) * Complex(1, 2)
391      puts a == Complex(0.0, 84.0)
392    end;
393  end
394
395
396  def test_mul_with_redefining_rational_mult
397    assert_in_out_err([], <<-'end;', ['true'], [])
398      class Rational
399        remove_method :*
400        def *(other); 355/113r; end
401      end
402      a = Complex(2r, 0r) * Complex(1, 2)
403      puts a == Complex(0r, 2*355/113r)
404    end;
405  end
406
407  def test_div
408    c = Complex(1,2)
409    c2 = Complex(2,3)
410
411    assert_equal(Complex(Rational(8,13),Rational(1,13)), c / c2)
412
413    c = Complex(1.0,2.0)
414    c2 = Complex(2.0,3.0)
415
416    r = c / c2
417    assert_in_delta(0.615, r.real, 0.001)
418    assert_in_delta(0.076, r.imag, 0.001)
419
420    c = Complex(1,2)
421    c2 = Complex(2,3)
422
423    assert_equal(Complex(Rational(1,2),1), c / 2)
424    assert_equal(Complex(0.5,1.0), c / 2.0)
425
426    assert_equal(Complex(Rational(1,2),Rational(1)), c / Rational(2))
427    assert_equal(Complex(Rational(3,2),Rational(3)), c / Rational(2,3))
428
429    c = Complex(1)
430    r = c / c
431    assert_instance_of(Complex, r)
432    assert_equal(1, r)
433    assert_predicate(r.real, :integer?)
434    assert_predicate(r.imag, :integer?)
435  end
436
437  def test_quo
438    c = Complex(1,2)
439    c2 = Complex(2,3)
440
441    assert_equal(Complex(Rational(8,13),Rational(1,13)), c.quo(c2))
442
443    c = Complex(1.0,2.0)
444    c2 = Complex(2.0,3.0)
445
446    r = c.quo(c2)
447    assert_in_delta(0.615, r.real, 0.001)
448    assert_in_delta(0.076, r.imag, 0.001)
449
450    c = Complex(1,2)
451    c2 = Complex(2,3)
452
453    assert_equal(Complex(Rational(1,2),1), c.quo(2))
454    assert_equal(Complex(0.5,1.0), c.quo(2.0))
455
456    assert_equal(Complex(Rational(1,2),Rational(1)), c / Rational(2))
457    assert_equal(Complex(Rational(3,2),Rational(3)), c / Rational(2,3))
458  end
459
460  def test_fdiv
461    c = Complex(1,2)
462    c2 = Complex(2,3)
463
464    r = c.fdiv(c2)
465    assert_in_delta(0.615, r.real, 0.001)
466    assert_in_delta(0.076, r.imag, 0.001)
467
468    c = Complex(1.0,2.0)
469    c2 = Complex(2.0,3.0)
470
471    r = c.fdiv(c2)
472    assert_in_delta(0.615, r.real, 0.001)
473    assert_in_delta(0.076, r.imag, 0.001)
474
475    c = Complex(1,2)
476    c2 = Complex(2,3)
477
478    assert_equal(Complex(0.5,1.0), c.fdiv(2))
479    assert_equal(Complex(0.5,1.0), c.fdiv(2.0))
480  end
481
482  def test_expt
483    c = Complex(1,2)
484    c2 = Complex(2,3)
485
486    r = c ** c2
487    assert_in_delta(-0.015, r.real, 0.001)
488    assert_in_delta(-0.179, r.imag, 0.001)
489
490    assert_equal(Complex(-3,4), c ** 2)
491    assert_equal(Complex(Rational(-3,25),Rational(-4,25)), c ** -2)
492
493    r = c ** 2.0
494    assert_in_delta(-3.0, r.real, 0.001)
495    assert_in_delta(4.0, r.imag, 0.001)
496
497    r = c ** -2.0
498    assert_in_delta(-0.12, r.real, 0.001)
499    assert_in_delta(-0.16, r.imag, 0.001)
500
501    assert_equal(Complex(-3,4), c ** Rational(2))
502    assert_equal(Complex(Rational(-3,25),Rational(-4,25)),
503      c ** Rational(-2)) # why failed?
504
505    r = c ** Rational(2,3)
506    assert_in_delta(1.264, r.real, 0.001)
507    assert_in_delta(1.150, r.imag, 0.001)
508
509    r = c ** Rational(-2,3)
510    assert_in_delta(0.432, r.real, 0.001)
511    assert_in_delta(-0.393, r.imag, 0.001)
512
513    c = Complex(0.0, -888888888888888.0)**8888
514    assert_not_predicate(c.real, :nan?)
515    assert_not_predicate(c.imag, :nan?)
516  end
517
518  def test_cmp
519    assert_raise(NoMethodError){1 <=> Complex(1,1)}
520    assert_raise(NoMethodError){Complex(1,1) <=> 1}
521    assert_raise(NoMethodError){Complex(1,1) <=> Complex(1,1)}
522  end
523
524  def test_eqeq
525    assert_equal(Complex(1), Complex(1,0))
526    assert_equal(Complex(-1), Complex(-1,0))
527
528    assert_not_equal(Complex(1), Complex(2,1))
529    assert_operator(Complex(2,1), :!=, Complex(1))
530    assert_not_equal(nil, Complex(1))
531    assert_not_equal('', Complex(1))
532
533    nan = 0.0 / 0
534    if nan.nan? && nan != nan
535      assert_not_equal(Complex(nan, 0), Complex(nan, 0))
536      assert_not_equal(Complex(0, nan), Complex(0, nan))
537      assert_not_equal(Complex(nan, nan), Complex(nan, nan))
538    end
539  end
540
541  def test_coerce
542    assert_equal([Complex(2),Complex(1)], Complex(1).coerce(2))
543    assert_equal([Complex(2.2),Complex(1)], Complex(1).coerce(2.2))
544    assert_equal([Complex(Rational(2)),Complex(1)],
545		 Complex(1).coerce(Rational(2)))
546    assert_equal([Complex(2),Complex(1)], Complex(1).coerce(Complex(2)))
547
548    obj = eval("class C\u{1f5ff}; self; end").new
549    assert_raise_with_message(TypeError, /C\u{1f5ff}/) { Complex(1).coerce(obj) }
550  end
551
552  class ObjectX
553    def +(x) Rational(1) end
554    alias - +
555    alias * +
556    alias / +
557    alias quo +
558    alias ** +
559    def coerce(x) [x, Complex(1)] end
560  end
561
562  def test_coerce2
563    x = ObjectX.new
564    %w(+ - * / quo **).each do |op|
565      assert_kind_of(Numeric, Complex(1).__send__(op, x))
566    end
567  end
568
569  def test_math
570    c = Complex(1,2)
571
572    assert_in_delta(2.236, c.abs, 0.001)
573    assert_in_delta(2.236, c.magnitude, 0.001)
574    assert_equal(5, c.abs2)
575
576    assert_equal(c.abs, Math.sqrt(c * c.conj))
577    assert_equal(c.abs, Math.sqrt(c.real**2 + c.imag**2))
578    assert_equal(c.abs2, c * c.conj)
579    assert_equal(c.abs2, c.real**2 + c.imag**2)
580
581    assert_in_delta(1.107, c.arg, 0.001)
582    assert_in_delta(1.107, c.angle, 0.001)
583    assert_in_delta(1.107, c.phase, 0.001)
584
585    r = c.polar
586    assert_in_delta(2.236, r[0], 0.001)
587    assert_in_delta(1.107, r[1], 0.001)
588    assert_equal(Complex(1,-2), c.conjugate)
589    assert_equal(Complex(1,-2), c.conj)
590
591    assert_equal(Complex(1,2), c.numerator)
592    assert_equal(1, c.denominator)
593  end
594
595  def test_to_s
596    c = Complex(1,2)
597
598    assert_instance_of(String, c.to_s)
599    assert_equal('1+2i', c.to_s)
600
601    assert_equal('0+2i', Complex(0,2).to_s)
602    assert_equal('0-2i', Complex(0,-2).to_s)
603    assert_equal('1+2i', Complex(1,2).to_s)
604    assert_equal('-1+2i', Complex(-1,2).to_s)
605    assert_equal('-1-2i', Complex(-1,-2).to_s)
606    assert_equal('1-2i', Complex(1,-2).to_s)
607    assert_equal('-1-2i', Complex(-1,-2).to_s)
608
609    assert_equal('0+2.0i', Complex(0,2.0).to_s)
610    assert_equal('0-2.0i', Complex(0,-2.0).to_s)
611    assert_equal('1.0+2.0i', Complex(1.0,2.0).to_s)
612    assert_equal('-1.0+2.0i', Complex(-1.0,2.0).to_s)
613    assert_equal('-1.0-2.0i', Complex(-1.0,-2.0).to_s)
614    assert_equal('1.0-2.0i', Complex(1.0,-2.0).to_s)
615    assert_equal('-1.0-2.0i', Complex(-1.0,-2.0).to_s)
616
617    assert_equal('0+2/1i', Complex(0,Rational(2)).to_s)
618    assert_equal('0-2/1i', Complex(0,Rational(-2)).to_s)
619    assert_equal('1+2/1i', Complex(1,Rational(2)).to_s)
620    assert_equal('-1+2/1i', Complex(-1,Rational(2)).to_s)
621    assert_equal('-1-2/1i', Complex(-1,Rational(-2)).to_s)
622    assert_equal('1-2/1i', Complex(1,Rational(-2)).to_s)
623    assert_equal('-1-2/1i', Complex(-1,Rational(-2)).to_s)
624
625    assert_equal('0+2/3i', Complex(0,Rational(2,3)).to_s)
626    assert_equal('0-2/3i', Complex(0,Rational(-2,3)).to_s)
627    assert_equal('1+2/3i', Complex(1,Rational(2,3)).to_s)
628    assert_equal('-1+2/3i', Complex(-1,Rational(2,3)).to_s)
629    assert_equal('-1-2/3i', Complex(-1,Rational(-2,3)).to_s)
630    assert_equal('1-2/3i', Complex(1,Rational(-2,3)).to_s)
631    assert_equal('-1-2/3i', Complex(-1,Rational(-2,3)).to_s)
632
633    nan = 0.0 / 0
634    inf = 1.0 / 0
635    if nan.nan?
636      assert_equal('NaN+NaN*i', Complex(nan,nan).to_s)
637    end
638    if inf.infinite?
639      assert_equal('Infinity+Infinity*i', Complex(inf,inf).to_s)
640      assert_equal('Infinity-Infinity*i', Complex(inf,-inf).to_s)
641    end
642  end
643
644  def test_inspect
645    c = Complex(1,2)
646
647    assert_instance_of(String, c.inspect)
648    assert_equal('(1+2i)', c.inspect)
649  end
650
651  def test_marshal
652    c = Complex(1,2)
653
654    s = Marshal.dump(c)
655    c2 = Marshal.load(s)
656    assert_equal(c, c2)
657    assert_instance_of(Complex, c2)
658
659    c = Complex(Rational(1,2),Rational(2,3))
660
661    s = Marshal.dump(c)
662    c2 = Marshal.load(s)
663    assert_equal(c, c2)
664    assert_instance_of(Complex, c2)
665
666    bug3656 = '[ruby-core:31622]'
667    c = Complex(1,2)
668    assert_predicate(c, :frozen?)
669    result = c.marshal_load([2,3]) rescue :fail
670    assert_equal(:fail, result, bug3656)
671    assert_equal(Complex(1,2), c)
672  end
673
674  def test_marshal_compatibility
675    bug6625 = '[ruby-core:45775]'
676    dump = "\x04\x08o:\x0cComplex\x07:\x0a@reali\x06:\x0b@imagei\x07"
677    assert_nothing_raised(bug6625) do
678      assert_equal(Complex(1, 2), Marshal.load(dump), bug6625)
679    end
680  end
681
682  def test_parse
683    assert_equal(Complex(5), '5'.to_c)
684    assert_equal(Complex(-5), '-5'.to_c)
685    assert_equal(Complex(5,3), '5+3i'.to_c)
686    assert_equal(Complex(-5,3), '-5+3i'.to_c)
687    assert_equal(Complex(5,-3), '5-3i'.to_c)
688    assert_equal(Complex(-5,-3), '-5-3i'.to_c)
689    assert_equal(Complex(0,3), '3i'.to_c)
690    assert_equal(Complex(0,-3), '-3i'.to_c)
691    assert_equal(Complex(5,1), '5+i'.to_c)
692    assert_equal(Complex(0,1), 'i'.to_c)
693    assert_equal(Complex(0,1), '+i'.to_c)
694    assert_equal(Complex(0,-1), '-i'.to_c)
695
696    assert_equal(Complex(5,3), '5+3I'.to_c)
697    assert_equal(Complex(5,3), '5+3j'.to_c)
698    assert_equal(Complex(5,3), '5+3J'.to_c)
699    assert_equal(Complex(0,3), '3I'.to_c)
700    assert_equal(Complex(0,3), '3j'.to_c)
701    assert_equal(Complex(0,3), '3J'.to_c)
702    assert_equal(Complex(0,1), 'I'.to_c)
703    assert_equal(Complex(0,1), 'J'.to_c)
704
705    assert_equal(Complex(5.0), '5.0'.to_c)
706    assert_equal(Complex(-5.0), '-5.0'.to_c)
707    assert_equal(Complex(5.0,3.0), '5.0+3.0i'.to_c)
708    assert_equal(Complex(-5.0,3.0), '-5.0+3.0i'.to_c)
709    assert_equal(Complex(5.0,-3.0), '5.0-3.0i'.to_c)
710    assert_equal(Complex(-5.0,-3.0), '-5.0-3.0i'.to_c)
711    assert_equal(Complex(0.0,3.0), '3.0i'.to_c)
712    assert_equal(Complex(0.0,-3.0), '-3.0i'.to_c)
713
714    assert_equal(Complex(5.1), '5.1'.to_c)
715    assert_equal(Complex(-5.2), '-5.2'.to_c)
716    assert_equal(Complex(5.3,3.4), '5.3+3.4i'.to_c)
717    assert_equal(Complex(-5.5,3.6), '-5.5+3.6i'.to_c)
718    assert_equal(Complex(5.3,-3.4), '5.3-3.4i'.to_c)
719    assert_equal(Complex(-5.5,-3.6), '-5.5-3.6i'.to_c)
720    assert_equal(Complex(0.0,3.1), '3.1i'.to_c)
721    assert_equal(Complex(0.0,-3.2), '-3.2i'.to_c)
722
723    assert_equal(Complex(5.0), '5e0'.to_c)
724    assert_equal(Complex(-5.0), '-5e0'.to_c)
725    assert_equal(Complex(5.0,3.0), '5e0+3e0i'.to_c)
726    assert_equal(Complex(-5.0,3.0), '-5e0+3e0i'.to_c)
727    assert_equal(Complex(5.0,-3.0), '5e0-3e0i'.to_c)
728    assert_equal(Complex(-5.0,-3.0), '-5e0-3e0i'.to_c)
729    assert_equal(Complex(0.0,3.0), '3e0i'.to_c)
730    assert_equal(Complex(0.0,-3.0), '-3e0i'.to_c)
731
732    assert_equal(Complex(5e1), '5e1'.to_c)
733    assert_equal(Complex(-5e2), '-5e2'.to_c)
734    assert_equal(Complex(5e3,3e4), '5e003+3e4i'.to_c)
735    assert_equal(Complex(-5e5,3e6), '-5e5+3e006i'.to_c)
736    assert_equal(Complex(5e3,-3e4), '5e003-3e4i'.to_c)
737    assert_equal(Complex(-5e5,-3e6), '-5e5-3e006i'.to_c)
738    assert_equal(Complex(0.0,3e1), '3e1i'.to_c)
739    assert_equal(Complex(0.0,-3e2), '-3e2i'.to_c)
740
741    assert_equal(Complex(0.33), '.33'.to_c)
742    assert_equal(Complex(0.33), '0.33'.to_c)
743    assert_equal(Complex(-0.33), '-.33'.to_c)
744    assert_equal(Complex(-0.33), '-0.33'.to_c)
745    assert_equal(Complex(-0.33), '-0.3_3'.to_c)
746
747    assert_equal(Complex.polar(10,10), '10@10'.to_c)
748    assert_equal(Complex.polar(-10,-10), '-10@-10'.to_c)
749    assert_equal(Complex.polar(10.5,10.5), '10.5@10.5'.to_c)
750    assert_equal(Complex.polar(-10.5,-10.5), '-10.5@-10.5'.to_c)
751
752    assert_equal(Complex(5), Complex('5'))
753    assert_equal(Complex(-5), Complex('-5'))
754    assert_equal(Complex(5,3), Complex('5+3i'))
755    assert_equal(Complex(-5,3), Complex('-5+3i'))
756    assert_equal(Complex(5,-3), Complex('5-3i'))
757    assert_equal(Complex(-5,-3), Complex('-5-3i'))
758    assert_equal(Complex(0,3), Complex('3i'))
759    assert_equal(Complex(0,-3), Complex('-3i'))
760    assert_equal(Complex(5,1), Complex('5+i'))
761    assert_equal(Complex(0,1), Complex('i'))
762    assert_equal(Complex(0,1), Complex('+i'))
763    assert_equal(Complex(0,-1), Complex('-i'))
764
765    assert_equal(Complex(5,3), Complex('5+3I'))
766    assert_equal(Complex(5,3), Complex('5+3j'))
767    assert_equal(Complex(5,3), Complex('5+3J'))
768    assert_equal(Complex(0,3), Complex('3I'))
769    assert_equal(Complex(0,3), Complex('3j'))
770    assert_equal(Complex(0,3), Complex('3J'))
771    assert_equal(Complex(0,1), Complex('I'))
772    assert_equal(Complex(0,1), Complex('J'))
773
774    assert_equal(Complex(5.0), Complex('5.0'))
775    assert_equal(Complex(-5.0), Complex('-5.0'))
776    assert_equal(Complex(5.0,3.0), Complex('5.0+3.0i'))
777    assert_equal(Complex(-5.0,3.0), Complex('-5.0+3.0i'))
778    assert_equal(Complex(5.0,-3.0), Complex('5.0-3.0i'))
779    assert_equal(Complex(-5.0,-3.0), Complex('-5.0-3.0i'))
780    assert_equal(Complex(0.0,3.0), Complex('3.0i'))
781    assert_equal(Complex(0.0,-3.0), Complex('-3.0i'))
782
783    assert_equal(Complex(5.1), Complex('5.1'))
784    assert_equal(Complex(-5.2), Complex('-5.2'))
785    assert_equal(Complex(5.3,3.4), Complex('5.3+3.4i'))
786    assert_equal(Complex(-5.5,3.6), Complex('-5.5+3.6i'))
787    assert_equal(Complex(5.3,-3.4), Complex('5.3-3.4i'))
788    assert_equal(Complex(-5.5,-3.6), Complex('-5.5-3.6i'))
789    assert_equal(Complex(0.0,3.1), Complex('3.1i'))
790    assert_equal(Complex(0.0,-3.2), Complex('-3.2i'))
791
792    assert_equal(Complex(5.0), Complex('5e0'))
793    assert_equal(Complex(-5.0), Complex('-5e0'))
794    assert_equal(Complex(5.0,3.0), Complex('5e0+3e0i'))
795    assert_equal(Complex(-5.0,3.0), Complex('-5e0+3e0i'))
796    assert_equal(Complex(5.0,-3.0), Complex('5e0-3e0i'))
797    assert_equal(Complex(-5.0,-3.0), Complex('-5e0-3e0i'))
798    assert_equal(Complex(0.0,3.0), Complex('3e0i'))
799    assert_equal(Complex(0.0,-3.0), Complex('-3e0i'))
800
801    assert_equal(Complex(5e1), Complex('5e1'))
802    assert_equal(Complex(-5e2), Complex('-5e2'))
803    assert_equal(Complex(5e3,3e4), Complex('5e003+3e4i'))
804    assert_equal(Complex(-5e5,3e6), Complex('-5e5+3e006i'))
805    assert_equal(Complex(5e3,-3e4), Complex('5e003-3e4i'))
806    assert_equal(Complex(-5e5,-3e6), Complex('-5e5-3e006i'))
807    assert_equal(Complex(0.0,3e1), Complex('3e1i'))
808    assert_equal(Complex(0.0,-3e2), Complex('-3e2i'))
809
810    assert_equal(Complex(0.33), Complex('.33'))
811    assert_equal(Complex(0.33), Complex('0.33'))
812    assert_equal(Complex(-0.33), Complex('-.33'))
813    assert_equal(Complex(-0.33), Complex('-0.33'))
814    assert_equal(Complex(-0.33), Complex('-0.3_3'))
815
816    assert_equal(Complex.polar(10,10), Complex('10@10'))
817    assert_equal(Complex.polar(-10,-10), Complex('-10@-10'))
818    assert_equal(Complex.polar(10.5,10.5), Complex('10.5@10.5'))
819    assert_equal(Complex.polar(-10.5,-10.5), Complex('-10.5@-10.5'))
820
821    assert_equal(Complex(0), ''.to_c)
822    assert_equal(Complex(0), ' '.to_c)
823    assert_equal(Complex(5), "\f\n\r\t\v5\0".to_c)
824    assert_equal(Complex(0), '_'.to_c)
825    assert_equal(Complex(0), '_5'.to_c)
826    assert_equal(Complex(5), '5_'.to_c)
827    assert_equal(Complex(5), '5x'.to_c)
828    assert_equal(Complex(5), '5+_3i'.to_c)
829    assert_equal(Complex(5), '5+3_i'.to_c)
830    assert_equal(Complex(5,3), '5+3i_'.to_c)
831    assert_equal(Complex(5,3), '5+3ix'.to_c)
832    assert_raise(ArgumentError){ Complex('')}
833    assert_raise(ArgumentError){ Complex('_')}
834    assert_raise(ArgumentError){ Complex("\f\n\r\t\v5\0")}
835    assert_raise(ArgumentError){ Complex('_5')}
836    assert_raise(ArgumentError){ Complex('5_')}
837    assert_raise(ArgumentError){ Complex('5x')}
838    assert_raise(ArgumentError){ Complex('5+_3i')}
839    assert_raise(ArgumentError){ Complex('5+3_i')}
840    assert_raise(ArgumentError){ Complex('5+3i_')}
841    assert_raise(ArgumentError){ Complex('5+3ix')}
842
843    assert_equal(Complex(Rational(1,5)), '1/5'.to_c)
844    assert_equal(Complex(Rational(-1,5)), '-1/5'.to_c)
845    assert_equal(Complex(Rational(1,5),3), '1/5+3i'.to_c)
846    assert_equal(Complex(Rational(1,5),-3), '1/5-3i'.to_c)
847    assert_equal(Complex(Rational(-1,5),3), '-1/5+3i'.to_c)
848    assert_equal(Complex(Rational(-1,5),-3), '-1/5-3i'.to_c)
849    assert_equal(Complex(Rational(1,5),Rational(3,2)), '1/5+3/2i'.to_c)
850    assert_equal(Complex(Rational(1,5),Rational(-3,2)), '1/5-3/2i'.to_c)
851    assert_equal(Complex(Rational(-1,5),Rational(3,2)), '-1/5+3/2i'.to_c)
852    assert_equal(Complex(Rational(-1,5),Rational(-3,2)), '-1/5-3/2i'.to_c)
853    assert_equal(Complex(Rational(1,5),Rational(3,2)), '1/5+3/2i'.to_c)
854    assert_equal(Complex(Rational(1,5),Rational(-3,2)), '1/5-3/2i'.to_c)
855    assert_equal(Complex(Rational(-1,5),Rational(3,2)), '-1/5+3/2i'.to_c)
856    assert_equal(Complex(Rational(-1,5),Rational(-3,2)), '-1/5-3/2i'.to_c)
857    assert_equal(Complex.polar(Rational(1,5),Rational(3,2)), Complex('1/5@3/2'))
858    assert_equal(Complex.polar(Rational(-1,5),Rational(-3,2)), Complex('-1/5@-3/2'))
859
860  end
861
862  def test_Complex_without_exception
863    assert_nothing_raised(ArgumentError){
864      assert_equal(nil, Complex('5x', exception: false))
865    }
866    assert_nothing_raised(ArgumentError){
867      assert_equal(nil, Complex(nil, exception: false))
868    }
869    assert_nothing_raised(ArgumentError){
870      assert_equal(nil, Complex(Object.new, exception: false))
871    }
872    assert_nothing_raised(ArgumentError){
873      assert_equal(nil, Complex(1, nil, exception: false))
874    }
875    assert_nothing_raised(ArgumentError){
876      assert_equal(nil, Complex(1, Object.new, exception: false))
877    }
878
879    o = Object.new
880    def o.to_c; raise; end
881    assert_nothing_raised(ArgumentError){
882      assert_equal(nil, Complex(o, exception: false))
883    }
884    assert_nothing_raised(ArgumentError){
885      assert_equal(nil, Complex(1, o, exception: false))
886    }
887  end
888
889  def test_respond
890    c = Complex(1,1)
891    assert_not_respond_to(c, :%)
892    assert_not_respond_to(c, :<=>)
893    assert_not_respond_to(c, :div)
894    assert_not_respond_to(c, :divmod)
895    assert_not_respond_to(c, :floor)
896    assert_not_respond_to(c, :ceil)
897    assert_not_respond_to(c, :modulo)
898    assert_not_respond_to(c, :remainder)
899    assert_not_respond_to(c, :round)
900    assert_not_respond_to(c, :step)
901    assert_not_respond_to(c, :tunrcate)
902
903    assert_not_respond_to(c, :positive?)
904    assert_not_respond_to(c, :negative?)
905    assert_not_respond_to(c, :sign)
906
907    assert_not_respond_to(c, :quotient)
908    assert_not_respond_to(c, :quot)
909    assert_not_respond_to(c, :quotrem)
910
911    assert_not_respond_to(c, :gcd)
912    assert_not_respond_to(c, :lcm)
913    assert_not_respond_to(c, :gcdlcm)
914
915    (Comparable.instance_methods(false) - Complex.instance_methods(false)).each do |n|
916      assert_not_respond_to(c, n, "Complex##{n}")
917    end
918  end
919
920  def test_to_i
921    assert_equal(3, Complex(3).to_i)
922    assert_equal(3, Integer(Complex(3)))
923    assert_raise(RangeError){Complex(3,2).to_i}
924    assert_raise(RangeError){Integer(Complex(3,2))}
925  end
926
927  def test_to_f
928    assert_equal(3.0, Complex(3).to_f)
929    assert_equal(3.0, Float(Complex(3)))
930    assert_raise(RangeError){Complex(3,2).to_f}
931    assert_raise(RangeError){Float(Complex(3,2))}
932  end
933
934  def test_to_r
935    assert_equal(Rational(3), Complex(3).to_r)
936    assert_equal(Rational(3), Rational(Complex(3)))
937    assert_raise(RangeError){Complex(3,2).to_r}
938    assert_raise(RangeError){Rational(Complex(3,2))}
939  end
940
941  def test_to_c
942    c = nil.to_c
943    assert_equal([0,0], [c.real, c.imag])
944
945    c = 0.to_c
946    assert_equal([0,0], [c.real, c.imag])
947
948    c = 1.to_c
949    assert_equal([1,0], [c.real, c.imag])
950
951    c = 1.1.to_c
952    assert_equal([1.1, 0], [c.real, c.imag])
953
954    c = Rational(1,2).to_c
955    assert_equal([Rational(1,2), 0], [c.real, c.imag])
956
957    c = Complex(1,2).to_c
958    assert_equal([1, 2], [c.real, c.imag])
959
960    if (0.0/0).nan?
961      assert_nothing_raised{(0.0/0).to_c}
962    end
963    if (1.0/0).infinite?
964      assert_nothing_raised{(1.0/0).to_c}
965    end
966  end
967
968  def test_finite_p
969    assert_predicate(1+1i, :finite?)
970    assert_predicate(1-1i, :finite?)
971    assert_predicate(-1+1i, :finite?)
972    assert_predicate(-1-1i, :finite?)
973    assert_not_predicate(Float::INFINITY + 1i, :finite?)
974    assert_not_predicate(Complex(1, Float::INFINITY), :finite?)
975    assert_predicate(Complex(Float::MAX, 0.0), :finite?)
976    assert_predicate(Complex(0.0, Float::MAX), :finite?)
977    assert_predicate(Complex(Float::MAX, Float::MAX), :finite?)
978    assert_not_predicate(Complex(Float::NAN, 0), :finite?)
979    assert_not_predicate(Complex(0, Float::NAN), :finite?)
980    assert_not_predicate(Complex(Float::NAN, Float::NAN), :finite?)
981  end
982
983  def test_infinite_p
984    assert_nil((1+1i).infinite?)
985    assert_nil((1-1i).infinite?)
986    assert_nil((-1+1i).infinite?)
987    assert_nil((-1-1i).infinite?)
988    assert_equal(1, (Float::INFINITY + 1i).infinite?)
989    assert_equal(1, (Float::INFINITY - 1i).infinite?)
990    assert_equal(1, (-Float::INFINITY + 1i).infinite?)
991    assert_equal(1, (-Float::INFINITY - 1i).infinite?)
992    assert_equal(1, Complex(1, Float::INFINITY).infinite?)
993    assert_equal(1, Complex(-1, Float::INFINITY).infinite?)
994    assert_equal(1, Complex(1, -Float::INFINITY).infinite?)
995    assert_equal(1, Complex(-1, -Float::INFINITY).infinite?)
996    assert_nil(Complex(Float::MAX, 0.0).infinite?)
997    assert_nil(Complex(0.0, Float::MAX).infinite?)
998    assert_nil(Complex(Float::MAX, Float::MAX).infinite?)
999    assert_nil(Complex(Float::NAN, 0).infinite?)
1000    assert_nil(Complex(0, Float::NAN).infinite?)
1001    assert_nil(Complex(Float::NAN, Float::NAN).infinite?)
1002  end
1003
1004  def test_supp
1005    assert_predicate(1, :real?)
1006    assert_predicate(1.1, :real?)
1007
1008    assert_equal(1, 1.real)
1009    assert_equal(0, 1.imag)
1010    assert_equal(0, 1.imaginary)
1011
1012    assert_equal(1.1, 1.1.real)
1013    assert_equal(0, 1.1.imag)
1014    assert_equal(0, 1.1.imaginary)
1015
1016    assert_equal(1, 1.magnitude)
1017    assert_equal(1, -1.magnitude)
1018    assert_equal(1, 1.0.magnitude)
1019    assert_equal(1, -1.0.magnitude)
1020
1021    assert_equal(4, 2.abs2)
1022    assert_equal(4, -2.abs2)
1023    assert_equal(4.0, 2.0.abs2)
1024    assert_equal(4.0, -2.0.abs2)
1025
1026    assert_equal(0, 1.arg)
1027    assert_equal(0, 1.angle)
1028    assert_equal(0, 1.phase)
1029
1030    assert_equal(0, 1.0.arg)
1031    assert_equal(0, 1.0.angle)
1032    assert_equal(0, 1.0.phase)
1033
1034    if (0.0/0).nan?
1035      nan = 0.0/0
1036      assert_same(nan, nan.arg)
1037      assert_same(nan, nan.angle)
1038      assert_same(nan, nan.phase)
1039    end
1040
1041    assert_equal(Math::PI, -1.arg)
1042    assert_equal(Math::PI, -1.angle)
1043    assert_equal(Math::PI, -1.phase)
1044
1045    assert_equal(Math::PI, -1.0.arg)
1046    assert_equal(Math::PI, -1.0.angle)
1047    assert_equal(Math::PI, -1.0.phase)
1048
1049    assert_equal([1,0], 1.rect)
1050    assert_equal([-1,0], -1.rect)
1051    assert_equal([1,0], 1.rectangular)
1052    assert_equal([-1,0], -1.rectangular)
1053
1054    assert_equal([1.0,0], 1.0.rect)
1055    assert_equal([-1.0,0], -1.0.rect)
1056    assert_equal([1.0,0], 1.0.rectangular)
1057    assert_equal([-1.0,0], -1.0.rectangular)
1058
1059    assert_equal([1,0], 1.polar)
1060    assert_equal([1, Math::PI], -1.polar)
1061
1062    assert_equal([1.0,0], 1.0.polar)
1063    assert_equal([1.0, Math::PI], -1.0.polar)
1064
1065    assert_equal(1, 1.conjugate)
1066    assert_equal(-1, -1.conjugate)
1067    assert_equal(1, 1.conj)
1068    assert_equal(-1, -1.conj)
1069
1070    assert_equal(1.1, 1.1.conjugate)
1071    assert_equal(-1.1, -1.1.conjugate)
1072    assert_equal(1.1, 1.1.conj)
1073    assert_equal(-1.1, -1.1.conj)
1074
1075    assert_equal(Complex(Rational(1,2),Rational(1)), Complex(1,2).quo(2))
1076
1077    assert_equal(0.5, 1.fdiv(2))
1078    assert_equal(5000000000.0, 10000000000.fdiv(2))
1079    assert_equal(0.5, 1.0.fdiv(2))
1080    assert_equal(0.25, Rational(1,2).fdiv(2))
1081    assert_equal(Complex(0.5,1.0), Complex(1,2).quo(2))
1082  end
1083
1084  def test_ruby19
1085    assert_raise(NoMethodError){ Complex.new(1) }
1086    assert_raise(NoMethodError){ Complex.new!(1) }
1087    assert_raise(NoMethodError){ Complex.reduce(1) }
1088  end
1089
1090  def test_fixed_bug
1091    assert_equal(Complex(1), 1 ** Complex(1))
1092    assert_equal('-1.0-0.0i', Complex(-1.0, -0.0).to_s)
1093    assert_in_delta(Math::PI, Complex(-0.0).arg, 0.001)
1094    assert_equal(Complex(2e3, 2e4), '2e3+2e4i'.to_c)
1095    assert_raise(ArgumentError){ Complex('--8i')}
1096  end
1097
1098  def test_known_bug
1099  end
1100
1101  def test_canonicalize_internal
1102    obj = Class.new(Numeric) do
1103      attr_accessor :real
1104      alias real? real
1105    end.new
1106    obj.real = true
1107    c = Complex.rect(obj, 1);
1108    obj.real = false
1109    c = c.conj
1110    assert_equal(obj, c.real)
1111    assert_equal(-1, c.imag)
1112  end
1113
1114  def test_canonicalize_polar
1115    obj = Class.new(Numeric) do
1116      def initialize
1117        @x = 2
1118      end
1119      def real?
1120        (@x -= 1) > 0
1121      end
1122    end.new
1123    assert_raise(TypeError) do
1124      Complex.polar(1, obj)
1125    end
1126  end
1127end
1128