Ruby  1.9.3p547(2014-05-14revision45962)
complex.c
Go to the documentation of this file.
1 /*
2  complex.c: Coded by Tadayoshi Funaba 2008-2011
3 
4  This implementation is based on Keiju Ishitsuka's Complex library
5  which is written in ruby.
6 */
7 
8 #include "ruby.h"
9 #include "internal.h"
10 #include <math.h>
11 
12 #define NDEBUG
13 #include <assert.h>
14 
15 #define ZERO INT2FIX(0)
16 #define ONE INT2FIX(1)
17 #define TWO INT2FIX(2)
18 
20 
25 
26 #define f_boolcast(x) ((x) ? Qtrue : Qfalse)
27 
28 #define binop(n,op) \
29 inline static VALUE \
30 f_##n(VALUE x, VALUE y)\
31 {\
32  return rb_funcall(x, (op), 1, y);\
33 }
34 
35 #define fun1(n) \
36 inline static VALUE \
37 f_##n(VALUE x)\
38 {\
39  return rb_funcall(x, id_##n, 0);\
40 }
41 
42 #define fun2(n) \
43 inline static VALUE \
44 f_##n(VALUE x, VALUE y)\
45 {\
46  return rb_funcall(x, id_##n, 1, y);\
47 }
48 
49 #define math1(n) \
50 inline static VALUE \
51 m_##n(VALUE x)\
52 {\
53  return rb_funcall(rb_mMath, id_##n, 1, x);\
54 }
55 
56 #define math2(n) \
57 inline static VALUE \
58 m_##n(VALUE x, VALUE y)\
59 {\
60  return rb_funcall(rb_mMath, id_##n, 2, x, y);\
61 }
62 
63 #define PRESERVE_SIGNEDZERO
64 
65 inline static VALUE
67 {
68 #ifndef PRESERVE_SIGNEDZERO
69  if (FIXNUM_P(y) && FIX2LONG(y) == 0)
70  return x;
71  else if (FIXNUM_P(x) && FIX2LONG(x) == 0)
72  return y;
73 #endif
74  return rb_funcall(x, '+', 1, y);
75 }
76 
77 inline static VALUE
79 {
80  if (FIXNUM_P(x) && FIXNUM_P(y)) {
81  long c = FIX2LONG(x) - FIX2LONG(y);
82  if (c > 0)
83  c = 1;
84  else if (c < 0)
85  c = -1;
86  return INT2FIX(c);
87  }
88  return rb_funcall(x, id_cmp, 1, y);
89 }
90 
91 inline static VALUE
93 {
94  if (FIXNUM_P(y) && FIX2LONG(y) == 1)
95  return x;
96  return rb_funcall(x, '/', 1, y);
97 }
98 
99 inline static VALUE
101 {
102  if (FIXNUM_P(x) && FIXNUM_P(y))
103  return f_boolcast(FIX2LONG(x) > FIX2LONG(y));
104  return rb_funcall(x, '>', 1, y);
105 }
106 
107 inline static VALUE
109 {
110  if (FIXNUM_P(x) && FIXNUM_P(y))
111  return f_boolcast(FIX2LONG(x) < FIX2LONG(y));
112  return rb_funcall(x, '<', 1, y);
113 }
114 
115 binop(mod, '%')
116 
117 inline static VALUE
118 f_mul(VALUE x, VALUE y)
119 {
120 #ifndef PRESERVE_SIGNEDZERO
121  if (FIXNUM_P(y)) {
122  long iy = FIX2LONG(y);
123  if (iy == 0) {
124  if (FIXNUM_P(x) || TYPE(x) == T_BIGNUM)
125  return ZERO;
126  }
127  else if (iy == 1)
128  return x;
129  }
130  else if (FIXNUM_P(x)) {
131  long ix = FIX2LONG(x);
132  if (ix == 0) {
133  if (FIXNUM_P(y) || TYPE(y) == T_BIGNUM)
134  return ZERO;
135  }
136  else if (ix == 1)
137  return y;
138  }
139 #endif
140  return rb_funcall(x, '*', 1, y);
141 }
142 
143 inline static VALUE
145 {
146 #ifndef PRESERVE_SIGNEDZERO
147  if (FIXNUM_P(y) && FIX2LONG(y) == 0)
148  return x;
149 #endif
150  return rb_funcall(x, '-', 1, y);
151 }
152 
153 fun1(abs)
154 fun1(abs2)
155 fun1(arg)
156 fun1(conj)
157 fun1(denominator)
158 fun1(floor)
159 fun1(imag)
160 fun1(inspect)
161 fun1(negate)
162 fun1(numerator)
163 fun1(real)
164 fun1(real_p)
165 
166 inline static VALUE
167 f_to_i(VALUE x)
168 {
169  if (TYPE(x) == T_STRING)
170  return rb_str_to_inum(x, 10, 0);
171  return rb_funcall(x, id_to_i, 0);
172 }
173 inline static VALUE
175 {
176  if (TYPE(x) == T_STRING)
177  return DBL2NUM(rb_str_to_dbl(x, 0));
178  return rb_funcall(x, id_to_f, 0);
179 }
180 
181 fun1(to_r)
182 fun1(to_s)
183 
184 fun2(divmod)
185 
186 inline static VALUE
187 f_eqeq_p(VALUE x, VALUE y)
188 {
189  if (FIXNUM_P(x) && FIXNUM_P(y))
190  return f_boolcast(FIX2LONG(x) == FIX2LONG(y));
191  return rb_funcall(x, id_eqeq_p, 1, y);
192 }
193 
194 fun2(expt)
195 fun2(fdiv)
196 fun2(idiv)
197 fun2(quo)
198 
199 inline static VALUE
201 {
202  if (FIXNUM_P(x))
203  return f_boolcast(FIX2LONG(x) < 0);
204  return rb_funcall(x, '<', 1, ZERO);
205 }
206 
207 #define f_positive_p(x) (!f_negative_p(x))
208 
209 inline static VALUE
211 {
212  switch (TYPE(x)) {
213  case T_FIXNUM:
214  return f_boolcast(FIX2LONG(x) == 0);
215  case T_BIGNUM:
216  return Qfalse;
217  case T_RATIONAL:
218  {
219  VALUE num = RRATIONAL(x)->num;
220 
221  return f_boolcast(FIXNUM_P(num) && FIX2LONG(num) == 0);
222  }
223  }
224  return rb_funcall(x, id_eqeq_p, 1, ZERO);
225 }
226 
227 #define f_nonzero_p(x) (!f_zero_p(x))
228 
229 inline static VALUE
231 {
232  switch (TYPE(x)) {
233  case T_FIXNUM:
234  return f_boolcast(FIX2LONG(x) == 1);
235  case T_BIGNUM:
236  return Qfalse;
237  case T_RATIONAL:
238  {
239  VALUE num = RRATIONAL(x)->num;
240  VALUE den = RRATIONAL(x)->den;
241 
242  return f_boolcast(FIXNUM_P(num) && FIX2LONG(num) == 1 &&
243  FIXNUM_P(den) && FIX2LONG(den) == 1);
244  }
245  }
246  return rb_funcall(x, id_eqeq_p, 1, ONE);
247 }
248 
249 inline static VALUE
251 {
252  return rb_obj_is_kind_of(x, c);
253 }
254 
255 inline static VALUE
257 {
258  return f_kind_of_p(x, rb_cNumeric);
259 }
260 
261 inline static VALUE
263 {
264  return f_kind_of_p(x, rb_cInteger);
265 }
266 
267 inline static VALUE
269 {
270  return f_kind_of_p(x, rb_cFixnum);
271 }
272 
273 inline static VALUE
275 {
276  return f_kind_of_p(x, rb_cBignum);
277 }
278 
279 inline static VALUE
281 {
282  return f_kind_of_p(x, rb_cFloat);
283 }
284 
285 inline static VALUE
287 {
288  return f_kind_of_p(x, rb_cRational);
289 }
290 
291 inline static VALUE
293 {
294  return f_kind_of_p(x, rb_cComplex);
295 }
296 
297 #define k_exact_p(x) (!k_float_p(x))
298 #define k_inexact_p(x) k_float_p(x)
299 
300 #define k_exact_zero_p(x) (k_exact_p(x) && f_zero_p(x))
301 #define k_exact_one_p(x) (k_exact_p(x) && f_one_p(x))
302 
303 #define get_dat1(x) \
304  struct RComplex *dat;\
305  dat = ((struct RComplex *)(x))
306 
307 #define get_dat2(x,y) \
308  struct RComplex *adat, *bdat;\
309  adat = ((struct RComplex *)(x));\
310  bdat = ((struct RComplex *)(y))
311 
312 inline static VALUE
314 {
315  NEWOBJ(obj, struct RComplex);
316  OBJSETUP(obj, klass, T_COMPLEX);
317 
318  obj->real = real;
319  obj->imag = imag;
320 
321  return (VALUE)obj;
322 }
323 
324 static VALUE
326 {
327  return nucomp_s_new_internal(klass, ZERO, ZERO);
328 }
329 
330 #if 0
331 static VALUE
332 nucomp_s_new_bang(int argc, VALUE *argv, VALUE klass)
333 {
334  VALUE real, imag;
335 
336  switch (rb_scan_args(argc, argv, "11", &real, &imag)) {
337  case 1:
338  if (!k_numeric_p(real))
339  real = f_to_i(real);
340  imag = ZERO;
341  break;
342  default:
343  if (!k_numeric_p(real))
344  real = f_to_i(real);
345  if (!k_numeric_p(imag))
346  imag = f_to_i(imag);
347  break;
348  }
349 
350  return nucomp_s_new_internal(klass, real, imag);
351 }
352 #endif
353 
354 inline static VALUE
356 {
357  assert(!k_complex_p(x));
358  return nucomp_s_new_internal(klass, x, ZERO);
359 }
360 
361 inline static VALUE
363 {
364  assert(!k_complex_p(x));
365  assert(!k_complex_p(y));
366  return nucomp_s_new_internal(klass, x, y);
367 }
368 
369 #ifdef CANONICALIZATION_FOR_MATHN
370 #define CANON
371 #endif
372 
373 #ifdef CANON
374 static int canonicalization = 0;
375 
378 {
379  canonicalization = f;
380 }
381 #endif
382 
383 inline static void
385 {
386  switch (TYPE(num)) {
387  case T_FIXNUM:
388  case T_BIGNUM:
389  case T_FLOAT:
390  case T_RATIONAL:
391  break;
392  default:
393  if (!k_numeric_p(num) || !f_real_p(num))
394  rb_raise(rb_eTypeError, "not a real");
395  }
396 }
397 
398 inline static VALUE
400 {
401 #ifdef CANON
402 #define CL_CANON
403 #ifdef CL_CANON
404  if (k_exact_zero_p(imag) && canonicalization)
405  return real;
406 #else
407  if (f_zero_p(imag) && canonicalization)
408  return real;
409 #endif
410 #endif
411  if (f_real_p(real) && f_real_p(imag))
412  return nucomp_s_new_internal(klass, real, imag);
413  else if (f_real_p(real)) {
414  get_dat1(imag);
415 
416  return nucomp_s_new_internal(klass,
417  f_sub(real, dat->imag),
418  f_add(ZERO, dat->real));
419  }
420  else if (f_real_p(imag)) {
421  get_dat1(real);
422 
423  return nucomp_s_new_internal(klass,
424  dat->real,
425  f_add(dat->imag, imag));
426  }
427  else {
428  get_dat2(real, imag);
429 
430  return nucomp_s_new_internal(klass,
431  f_sub(adat->real, bdat->imag),
432  f_add(adat->imag, bdat->real));
433  }
434 }
435 
436 /*
437  * call-seq:
438  * Complex.rect(real[, imag]) -> complex
439  * Complex.rectangular(real[, imag]) -> complex
440  *
441  * Returns a complex object which denotes the given rectangular form.
442  */
443 static VALUE
444 nucomp_s_new(int argc, VALUE *argv, VALUE klass)
445 {
446  VALUE real, imag;
447 
448  switch (rb_scan_args(argc, argv, "11", &real, &imag)) {
449  case 1:
450  nucomp_real_check(real);
451  imag = ZERO;
452  break;
453  default:
454  nucomp_real_check(real);
455  nucomp_real_check(imag);
456  break;
457  }
458 
459  return nucomp_s_canonicalize_internal(klass, real, imag);
460 }
461 
462 inline static VALUE
464 {
465  assert(!k_complex_p(x));
466  return nucomp_s_canonicalize_internal(klass, x, ZERO);
467 }
468 
469 inline static VALUE
471 {
472  assert(!k_complex_p(x));
473  return nucomp_s_canonicalize_internal(klass, x, y);
474 }
475 
476 /*
477  * call-seq:
478  * Complex(x[, y]) -> numeric
479  *
480  * Returns x+i*y;
481  */
482 static VALUE
483 nucomp_f_complex(int argc, VALUE *argv, VALUE klass)
484 {
485  return rb_funcall2(rb_cComplex, id_convert, argc, argv);
486 }
487 
488 #define imp1(n) \
489 inline static VALUE \
490 m_##n##_bang(VALUE x)\
491 {\
492  return rb_math_##n(x);\
493 }
494 
495 #define imp2(n) \
496 inline static VALUE \
497 m_##n##_bang(VALUE x, VALUE y)\
498 {\
499  return rb_math_##n(x, y);\
500 }
501 
502 imp2(atan2)
503 imp1(cos)
504 imp1(cosh)
505 imp1(exp)
506 imp2(hypot)
507 
508 #define m_hypot(x,y) m_hypot_bang((x),(y))
509 
510 static VALUE
511 m_log_bang(VALUE x)
512 {
513  return rb_math_log(1, &x);
514 }
515 
516 imp1(sin)
517 imp1(sinh)
518 imp1(sqrt)
519 
520 static VALUE
521 m_cos(VALUE x)
522 {
523  if (f_real_p(x))
524  return m_cos_bang(x);
525  {
526  get_dat1(x);
528  f_mul(m_cos_bang(dat->real),
529  m_cosh_bang(dat->imag)),
530  f_mul(f_negate(m_sin_bang(dat->real)),
531  m_sinh_bang(dat->imag)));
532  }
533 }
534 
535 static VALUE
537 {
538  if (f_real_p(x))
539  return m_sin_bang(x);
540  {
541  get_dat1(x);
543  f_mul(m_sin_bang(dat->real),
544  m_cosh_bang(dat->imag)),
545  f_mul(m_cos_bang(dat->real),
546  m_sinh_bang(dat->imag)));
547  }
548 }
549 
550 #if 0
551 static VALUE
552 m_sqrt(VALUE x)
553 {
554  if (f_real_p(x)) {
555  if (f_positive_p(x))
556  return m_sqrt_bang(x);
557  return f_complex_new2(rb_cComplex, ZERO, m_sqrt_bang(f_negate(x)));
558  }
559  else {
560  get_dat1(x);
561 
562  if (f_negative_p(dat->imag))
563  return f_conj(m_sqrt(f_conj(x)));
564  else {
565  VALUE a = f_abs(x);
567  m_sqrt_bang(f_div(f_add(a, dat->real), TWO)),
568  m_sqrt_bang(f_div(f_sub(a, dat->real), TWO)));
569  }
570  }
571 }
572 #endif
573 
574 inline static VALUE
576 {
577  assert(!k_complex_p(x));
578  assert(!k_complex_p(y));
579  return nucomp_s_canonicalize_internal(klass,
580  f_mul(x, m_cos(y)),
581  f_mul(x, m_sin(y)));
582 }
583 
584 /*
585  * call-seq:
586  * Complex.polar(abs[, arg]) -> complex
587  *
588  * Returns a complex object which denotes the given polar form.
589  *
590  * Complex.polar(3, 0) #=> (3.0+0.0i)
591  * Complex.polar(3, Math::PI/2) #=> (1.836909530733566e-16+3.0i)
592  * Complex.polar(3, Math::PI) #=> (-3.0+3.673819061467132e-16i)
593  * Complex.polar(3, -Math::PI/2) #=> (1.836909530733566e-16-3.0i)
594  */
595 static VALUE
596 nucomp_s_polar(int argc, VALUE *argv, VALUE klass)
597 {
598  VALUE abs, arg;
599 
600  switch (rb_scan_args(argc, argv, "11", &abs, &arg)) {
601  case 1:
602  nucomp_real_check(abs);
603  arg = ZERO;
604  break;
605  default:
606  nucomp_real_check(abs);
607  nucomp_real_check(arg);
608  break;
609  }
610  return f_complex_polar(klass, abs, arg);
611 }
612 
613 /*
614  * call-seq:
615  * cmp.real -> real
616  *
617  * Returns the real part.
618  */
619 static VALUE
621 {
622  get_dat1(self);
623  return dat->real;
624 }
625 
626 /*
627  * call-seq:
628  * cmp.imag -> real
629  * cmp.imaginary -> real
630  *
631  * Returns the imaginary part.
632  */
633 static VALUE
635 {
636  get_dat1(self);
637  return dat->imag;
638 }
639 
640 /*
641  * call-seq:
642  * -cmp -> complex
643  *
644  * Returns negation of the value.
645  */
646 static VALUE
648 {
649  get_dat1(self);
650  return f_complex_new2(CLASS_OF(self),
651  f_negate(dat->real), f_negate(dat->imag));
652 }
653 
654 inline static VALUE
655 f_addsub(VALUE self, VALUE other,
656  VALUE (*func)(VALUE, VALUE), ID id)
657 {
658  if (k_complex_p(other)) {
659  VALUE real, imag;
660 
661  get_dat2(self, other);
662 
663  real = (*func)(adat->real, bdat->real);
664  imag = (*func)(adat->imag, bdat->imag);
665 
666  return f_complex_new2(CLASS_OF(self), real, imag);
667  }
668  if (k_numeric_p(other) && f_real_p(other)) {
669  get_dat1(self);
670 
671  return f_complex_new2(CLASS_OF(self),
672  (*func)(dat->real, other), dat->imag);
673  }
674  return rb_num_coerce_bin(self, other, id);
675 }
676 
677 /*
678  * call-seq:
679  * cmp + numeric -> complex
680  *
681  * Performs addition.
682  */
683 static VALUE
684 nucomp_add(VALUE self, VALUE other)
685 {
686  return f_addsub(self, other, f_add, '+');
687 }
688 
689 /*
690  * call-seq:
691  * cmp - numeric -> complex
692  *
693  * Performs subtraction.
694  */
695 static VALUE
696 nucomp_sub(VALUE self, VALUE other)
697 {
698  return f_addsub(self, other, f_sub, '-');
699 }
700 
701 /*
702  * call-seq:
703  * cmp * numeric -> complex
704  *
705  * Performs multiplication.
706  */
707 static VALUE
708 nucomp_mul(VALUE self, VALUE other)
709 {
710  if (k_complex_p(other)) {
711  VALUE real, imag;
712 
713  get_dat2(self, other);
714 
715  real = f_sub(f_mul(adat->real, bdat->real),
716  f_mul(adat->imag, bdat->imag));
717  imag = f_add(f_mul(adat->real, bdat->imag),
718  f_mul(adat->imag, bdat->real));
719 
720  return f_complex_new2(CLASS_OF(self), real, imag);
721  }
722  if (k_numeric_p(other) && f_real_p(other)) {
723  get_dat1(self);
724 
725  return f_complex_new2(CLASS_OF(self),
726  f_mul(dat->real, other),
727  f_mul(dat->imag, other));
728  }
729  return rb_num_coerce_bin(self, other, '*');
730 }
731 
732 inline static VALUE
733 f_divide(VALUE self, VALUE other,
734  VALUE (*func)(VALUE, VALUE), ID id)
735 {
736  if (k_complex_p(other)) {
737  int flo;
738  get_dat2(self, other);
739 
740  flo = (k_float_p(adat->real) || k_float_p(adat->imag) ||
741  k_float_p(bdat->real) || k_float_p(bdat->imag));
742 
743  if (f_gt_p(f_abs(bdat->real), f_abs(bdat->imag))) {
744  VALUE r, n;
745 
746  r = (*func)(bdat->imag, bdat->real);
747  n = f_mul(bdat->real, f_add(ONE, f_mul(r, r)));
748  if (flo)
749  return f_complex_new2(CLASS_OF(self),
750  (*func)(self, n),
751  (*func)(f_negate(f_mul(self, r)), n));
752  return f_complex_new2(CLASS_OF(self),
753  (*func)(f_add(adat->real,
754  f_mul(adat->imag, r)), n),
755  (*func)(f_sub(adat->imag,
756  f_mul(adat->real, r)), n));
757  }
758  else {
759  VALUE r, n;
760 
761  r = (*func)(bdat->real, bdat->imag);
762  n = f_mul(bdat->imag, f_add(ONE, f_mul(r, r)));
763  if (flo)
764  return f_complex_new2(CLASS_OF(self),
765  (*func)(f_mul(self, r), n),
766  (*func)(f_negate(self), n));
767  return f_complex_new2(CLASS_OF(self),
768  (*func)(f_add(f_mul(adat->real, r),
769  adat->imag), n),
770  (*func)(f_sub(f_mul(adat->imag, r),
771  adat->real), n));
772  }
773  }
774  if (k_numeric_p(other) && f_real_p(other)) {
775  get_dat1(self);
776 
777  return f_complex_new2(CLASS_OF(self),
778  (*func)(dat->real, other),
779  (*func)(dat->imag, other));
780  }
781  return rb_num_coerce_bin(self, other, id);
782 }
783 
784 #define rb_raise_zerodiv() rb_raise(rb_eZeroDivError, "divided by 0")
785 
786 /*
787  * call-seq:
788  * cmp / numeric -> complex
789  * cmp.quo(numeric) -> complex
790  *
791  * Performs division.
792  *
793  * For example:
794  *
795  * Complex(10.0) / 3 #=> (3.3333333333333335+(0/1)*i)
796  * Complex(10) / 3 #=> ((10/3)+(0/1)*i) # not (3+0i)
797  */
798 static VALUE
799 nucomp_div(VALUE self, VALUE other)
800 {
801  return f_divide(self, other, f_quo, id_quo);
802 }
803 
804 #define nucomp_quo nucomp_div
805 
806 /*
807  * call-seq:
808  * cmp.fdiv(numeric) -> complex
809  *
810  * Performs division as each part is a float, never returns a float.
811  *
812  * For example:
813  *
814  * Complex(11,22).fdiv(3) #=> (3.6666666666666665+7.333333333333333i)
815  */
816 static VALUE
817 nucomp_fdiv(VALUE self, VALUE other)
818 {
819  return f_divide(self, other, f_fdiv, id_fdiv);
820 }
821 
822 inline static VALUE
824 {
825  return f_quo(ONE, x);
826 }
827 
828 /*
829  * call-seq:
830  * cmp ** numeric -> complex
831  *
832  * Performs exponentiation.
833  *
834  * For example:
835  *
836  * Complex('i') ** 2 #=> (-1+0i)
837  * Complex(-8) ** Rational(1,3) #=> (1.0000000000000002+1.7320508075688772i)
838  */
839 static VALUE
840 nucomp_expt(VALUE self, VALUE other)
841 {
842  if (k_numeric_p(other) && k_exact_zero_p(other))
843  return f_complex_new_bang1(CLASS_OF(self), ONE);
844 
845  if (k_rational_p(other) && f_one_p(f_denominator(other)))
846  other = f_numerator(other); /* c14n */
847 
848  if (k_complex_p(other)) {
849  get_dat1(other);
850 
851  if (k_exact_zero_p(dat->imag))
852  other = dat->real; /* c14n */
853  }
854 
855  if (k_complex_p(other)) {
856  VALUE r, theta, nr, ntheta;
857 
858  get_dat1(other);
859 
860  r = f_abs(self);
861  theta = f_arg(self);
862 
863  nr = m_exp_bang(f_sub(f_mul(dat->real, m_log_bang(r)),
864  f_mul(dat->imag, theta)));
865  ntheta = f_add(f_mul(theta, dat->real),
866  f_mul(dat->imag, m_log_bang(r)));
867  return f_complex_polar(CLASS_OF(self), nr, ntheta);
868  }
869  if (k_fixnum_p(other)) {
870  if (f_gt_p(other, ZERO)) {
871  VALUE x, z;
872  long n;
873 
874  x = self;
875  z = x;
876  n = FIX2LONG(other) - 1;
877 
878  while (n) {
879  long q, r;
880 
881  while (1) {
882  get_dat1(x);
883 
884  q = n / 2;
885  r = n % 2;
886 
887  if (r)
888  break;
889 
890  x = f_complex_new2(CLASS_OF(self),
891  f_sub(f_mul(dat->real, dat->real),
892  f_mul(dat->imag, dat->imag)),
893  f_mul(f_mul(TWO, dat->real), dat->imag));
894  n = q;
895  }
896  z = f_mul(z, x);
897  n--;
898  }
899  return z;
900  }
901  return f_expt(f_reciprocal(self), f_negate(other));
902  }
903  if (k_numeric_p(other) && f_real_p(other)) {
904  VALUE r, theta;
905 
906  if (k_bignum_p(other))
907  rb_warn("in a**b, b may be too big");
908 
909  r = f_abs(self);
910  theta = f_arg(self);
911 
912  return f_complex_polar(CLASS_OF(self), f_expt(r, other),
913  f_mul(theta, other));
914  }
915  return rb_num_coerce_bin(self, other, id_expt);
916 }
917 
918 /*
919  * call-seq:
920  * cmp == object -> true or false
921  *
922  * Returns true if cmp equals object numerically.
923  */
924 static VALUE
926 {
927  if (k_complex_p(other)) {
928  get_dat2(self, other);
929 
930  return f_boolcast(f_eqeq_p(adat->real, bdat->real) &&
931  f_eqeq_p(adat->imag, bdat->imag));
932  }
933  if (k_numeric_p(other) && f_real_p(other)) {
934  get_dat1(self);
935 
936  return f_boolcast(f_eqeq_p(dat->real, other) && f_zero_p(dat->imag));
937  }
938  return f_eqeq_p(other, self);
939 }
940 
941 /* :nodoc: */
942 static VALUE
944 {
945  if (k_numeric_p(other) && f_real_p(other))
946  return rb_assoc_new(f_complex_new_bang1(CLASS_OF(self), other), self);
947  if (TYPE(other) == T_COMPLEX)
948  return rb_assoc_new(other, self);
949 
950  rb_raise(rb_eTypeError, "%s can't be coerced into %s",
951  rb_obj_classname(other), rb_obj_classname(self));
952  return Qnil;
953 }
954 
955 /*
956  * call-seq:
957  * cmp.abs -> real
958  * cmp.magnitude -> real
959  *
960  * Returns the absolute part of its polar form.
961  */
962 static VALUE
964 {
965  get_dat1(self);
966 
967  if (f_zero_p(dat->real)) {
968  VALUE a = f_abs(dat->imag);
969  if (k_float_p(dat->real) && !k_float_p(dat->imag))
970  a = f_to_f(a);
971  return a;
972  }
973  if (f_zero_p(dat->imag)) {
974  VALUE a = f_abs(dat->real);
975  if (!k_float_p(dat->real) && k_float_p(dat->imag))
976  a = f_to_f(a);
977  return a;
978  }
979  return m_hypot(dat->real, dat->imag);
980 }
981 
982 /*
983  * call-seq:
984  * cmp.abs2 -> real
985  *
986  * Returns square of the absolute value.
987  */
988 static VALUE
990 {
991  get_dat1(self);
992  return f_add(f_mul(dat->real, dat->real),
993  f_mul(dat->imag, dat->imag));
994 }
995 
996 /*
997  * call-seq:
998  * cmp.arg -> float
999  * cmp.angle -> float
1000  * cmp.phase -> float
1001  *
1002  * Returns the angle part of its polar form.
1003  *
1004  * Complex.polar(3, Math::PI/2).arg #=> 1.5707963267948966
1005  *
1006  */
1007 static VALUE
1009 {
1010  get_dat1(self);
1011  return m_atan2_bang(dat->imag, dat->real);
1012 }
1013 
1014 /*
1015  * call-seq:
1016  * cmp.rect -> array
1017  * cmp.rectangular -> array
1018  *
1019  * Returns an array; [cmp.real, cmp.imag].
1020  */
1021 static VALUE
1023 {
1024  get_dat1(self);
1025  return rb_assoc_new(dat->real, dat->imag);
1026 }
1027 
1028 /*
1029  * call-seq:
1030  * cmp.polar -> array
1031  *
1032  * Returns an array; [cmp.abs, cmp.arg].
1033  */
1034 static VALUE
1036 {
1037  return rb_assoc_new(f_abs(self), f_arg(self));
1038 }
1039 
1040 /*
1041  * call-seq:
1042  * cmp.conj -> complex
1043  * cmp.conjugate -> complex
1044  *
1045  * Returns the complex conjugate.
1046  */
1047 static VALUE
1049 {
1050  get_dat1(self);
1051  return f_complex_new2(CLASS_OF(self), dat->real, f_negate(dat->imag));
1052 }
1053 
1054 #if 0
1055 /* :nodoc: */
1056 static VALUE
1057 nucomp_true(VALUE self)
1058 {
1059  return Qtrue;
1060 }
1061 #endif
1062 
1063 /*
1064  * call-seq:
1065  * cmp.real? -> false
1066  *
1067  * Returns false.
1068  */
1069 static VALUE
1071 {
1072  return Qfalse;
1073 }
1074 
1075 #if 0
1076 /* :nodoc: */
1077 static VALUE
1078 nucomp_exact_p(VALUE self)
1079 {
1080  get_dat1(self);
1081  return f_boolcast(k_exact_p(dat->real) && k_exact_p(dat->imag));
1082 }
1083 
1084 /* :nodoc: */
1085 static VALUE
1086 nucomp_inexact_p(VALUE self)
1087 {
1088  return f_boolcast(!nucomp_exact_p(self));
1089 }
1090 #endif
1091 
1092 /*
1093  * call-seq:
1094  * cmp.denominator -> integer
1095  *
1096  * Returns the denominator (lcm of both denominator - real and imag).
1097  *
1098  * See numerator.
1099  */
1100 static VALUE
1102 {
1103  get_dat1(self);
1104  return rb_lcm(f_denominator(dat->real), f_denominator(dat->imag));
1105 }
1106 
1107 /*
1108  * call-seq:
1109  * cmp.numerator -> numeric
1110  *
1111  * Returns the numerator.
1112  *
1113  * For example:
1114  *
1115  * 1 2 3+4i <- numerator
1116  * - + -i -> ----
1117  * 2 3 6 <- denominator
1118  *
1119  * c = Complex('1/2+2/3i') #=> ((1/2)+(2/3)*i)
1120  * n = c.numerator #=> (3+4i)
1121  * d = c.denominator #=> 6
1122  * n / d #=> ((1/2)+(2/3)*i)
1123  * Complex(Rational(n.real, d), Rational(n.imag, d))
1124  * #=> ((1/2)+(2/3)*i)
1125  * See denominator.
1126  */
1127 static VALUE
1129 {
1130  VALUE cd;
1131 
1132  get_dat1(self);
1133 
1134  cd = f_denominator(self);
1135  return f_complex_new2(CLASS_OF(self),
1136  f_mul(f_numerator(dat->real),
1137  f_div(cd, f_denominator(dat->real))),
1138  f_mul(f_numerator(dat->imag),
1139  f_div(cd, f_denominator(dat->imag))));
1140 }
1141 
1142 /* :nodoc: */
1143 static VALUE
1145 {
1146  st_index_t v, h[2];
1147  VALUE n;
1148 
1149  get_dat1(self);
1150  n = rb_hash(dat->real);
1151  h[0] = NUM2LONG(n);
1152  n = rb_hash(dat->imag);
1153  h[1] = NUM2LONG(n);
1154  v = rb_memhash(h, sizeof(h));
1155  return LONG2FIX(v);
1156 }
1157 
1158 /* :nodoc: */
1159 static VALUE
1161 {
1162  if (k_complex_p(other)) {
1163  get_dat2(self, other);
1164 
1165  return f_boolcast((CLASS_OF(adat->real) == CLASS_OF(bdat->real)) &&
1166  (CLASS_OF(adat->imag) == CLASS_OF(bdat->imag)) &&
1167  f_eqeq_p(self, other));
1168 
1169  }
1170  return Qfalse;
1171 }
1172 
1173 inline static VALUE
1175 {
1176 #if defined(HAVE_SIGNBIT) && defined(__GNUC__) && defined(__sun__) && \
1177  !defined(signbit)
1178  extern int signbit(double);
1179 #endif
1180  switch (TYPE(x)) {
1181  case T_FLOAT: {
1182  double f = RFLOAT_VALUE(x);
1183  return f_boolcast(!isnan(f) && signbit(f));
1184  }
1185  }
1186  return f_negative_p(x);
1187 }
1188 
1189 inline static VALUE
1191 {
1192  return f_boolcast(!f_signbit(x));
1193 }
1194 
1195 static VALUE
1197 {
1198  VALUE s, impos;
1199 
1200  get_dat1(self);
1201 
1202  impos = f_tpositive_p(dat->imag);
1203 
1204  s = (*func)(dat->real);
1205  rb_str_cat2(s, !impos ? "-" : "+");
1206 
1207  rb_str_concat(s, (*func)(f_abs(dat->imag)));
1208  if (!rb_isdigit(RSTRING_PTR(s)[RSTRING_LEN(s) - 1]))
1209  rb_str_cat2(s, "*");
1210  rb_str_cat2(s, "i");
1211 
1212  return s;
1213 }
1214 
1215 /*
1216  * call-seq:
1217  * cmp.to_s -> string
1218  *
1219  * Returns the value as a string.
1220  */
1221 static VALUE
1223 {
1224  return f_format(self, f_to_s);
1225 }
1226 
1227 /*
1228  * call-seq:
1229  * cmp.inspect -> string
1230  *
1231  * Returns the value as a string for inspection.
1232  */
1233 static VALUE
1235 {
1236  VALUE s;
1237 
1238  s = rb_usascii_str_new2("(");
1239  rb_str_concat(s, f_format(self, f_inspect));
1240  rb_str_cat2(s, ")");
1241 
1242  return s;
1243 }
1244 
1245 /* :nodoc: */
1246 static VALUE
1248 {
1249  VALUE a;
1250  get_dat1(self);
1251 
1252  a = rb_assoc_new(dat->real, dat->imag);
1253  rb_copy_generic_ivar(a, self);
1254  return a;
1255 }
1256 
1257 /* :nodoc: */
1258 static VALUE
1260 {
1261  get_dat1(self);
1262  Check_Type(a, T_ARRAY);
1263  if (RARRAY_LEN(a) != 2)
1264  rb_raise(rb_eArgError, "marshaled complex must have an array whose length is 2 but %ld", RARRAY_LEN(a));
1265  dat->real = RARRAY_PTR(a)[0];
1266  dat->imag = RARRAY_PTR(a)[1];
1267  rb_copy_generic_ivar(self, a);
1268  return self;
1269 }
1270 
1271 /* --- */
1272 
1273 VALUE
1275 {
1276  return nucomp_s_new_internal(rb_cComplex, x, y);
1277 }
1278 
1279 VALUE
1281 {
1283 }
1284 
1285 VALUE
1287 {
1288  return f_complex_polar(rb_cComplex, x, y);
1289 }
1290 
1291 static VALUE nucomp_s_convert(int argc, VALUE *argv, VALUE klass);
1292 
1293 VALUE
1295 {
1296  VALUE a[2];
1297  a[0] = x;
1298  a[1] = y;
1299  return nucomp_s_convert(2, a, rb_cComplex);
1300 }
1301 
1302 /*
1303  * call-seq:
1304  * cmp.to_i -> integer
1305  *
1306  * Returns the value as an integer if possible.
1307  */
1308 static VALUE
1310 {
1311  get_dat1(self);
1312 
1313  if (k_inexact_p(dat->imag) || f_nonzero_p(dat->imag)) {
1314  VALUE s = f_to_s(self);
1315  rb_raise(rb_eRangeError, "can't convert %s into Integer",
1316  StringValuePtr(s));
1317  }
1318  return f_to_i(dat->real);
1319 }
1320 
1321 /*
1322  * call-seq:
1323  * cmp.to_f -> float
1324  *
1325  * Returns the value as a float if possible.
1326  */
1327 static VALUE
1329 {
1330  get_dat1(self);
1331 
1332  if (k_inexact_p(dat->imag) || f_nonzero_p(dat->imag)) {
1333  VALUE s = f_to_s(self);
1334  rb_raise(rb_eRangeError, "can't convert %s into Float",
1335  StringValuePtr(s));
1336  }
1337  return f_to_f(dat->real);
1338 }
1339 
1340 /*
1341  * call-seq:
1342  * cmp.to_r -> rational
1343  *
1344  * If the imaginary part is exactly 0, returns the real part as a Rational,
1345  * otherwise a RangeError is raised.
1346  */
1347 static VALUE
1349 {
1350  get_dat1(self);
1351 
1352  if (k_inexact_p(dat->imag) || f_nonzero_p(dat->imag)) {
1353  VALUE s = f_to_s(self);
1354  rb_raise(rb_eRangeError, "can't convert %s into Rational",
1355  StringValuePtr(s));
1356  }
1357  return f_to_r(dat->real);
1358 }
1359 
1360 /*
1361  * call-seq:
1362  * cmp.rationalize([eps]) -> rational
1363  *
1364  * If the imaginary part is exactly 0, returns the real part as a Rational,
1365  * otherwise a RangeError is raised.
1366  */
1367 static VALUE
1368 nucomp_rationalize(int argc, VALUE *argv, VALUE self)
1369 {
1370  get_dat1(self);
1371 
1372  rb_scan_args(argc, argv, "01", NULL);
1373 
1374  if (k_inexact_p(dat->imag) || f_nonzero_p(dat->imag)) {
1375  VALUE s = f_to_s(self);
1376  rb_raise(rb_eRangeError, "can't convert %s into Rational",
1377  StringValuePtr(s));
1378  }
1379  return rb_funcall2(dat->real, rb_intern("rationalize"), argc, argv);
1380 }
1381 
1382 /*
1383  * call-seq:
1384  * nil.to_c -> (0+0i)
1385  *
1386  * Returns zero as a complex.
1387  */
1388 static VALUE
1390 {
1391  return rb_complex_new1(INT2FIX(0));
1392 }
1393 
1394 /*
1395  * call-seq:
1396  * num.to_c -> complex
1397  *
1398  * Returns the value as a complex.
1399  */
1400 static VALUE
1402 {
1403  return rb_complex_new1(self);
1404 }
1405 
1408 
1409 #define WS "\\s*"
1410 #define DIGITS "(?:[0-9](?:_[0-9]|[0-9])*)"
1411 #define NUMERATOR "(?:" DIGITS "?\\.)?" DIGITS "(?:[eE][-+]?" DIGITS ")?"
1412 #define DENOMINATOR DIGITS
1413 #define NUMBER "[-+]?" NUMERATOR "(?:\\/" DENOMINATOR ")?"
1414 #define NUMBERNOS NUMERATOR "(?:\\/" DENOMINATOR ")?"
1415 #define PATTERN0 "\\A" WS "(" NUMBER ")@(" NUMBER ")" WS
1416 #define PATTERN1 "\\A" WS "([-+])?(" NUMBER ")?[iIjJ]" WS
1417 #define PATTERN2 "\\A" WS "(" NUMBER ")(([-+])(" NUMBERNOS ")?[iIjJ])?" WS
1418 
1419 static void
1421 {
1422  static const char comp_pat0_source[] = PATTERN0;
1423  static const char comp_pat1_source[] = PATTERN1;
1424  static const char comp_pat2_source[] = PATTERN2;
1425  static const char underscores_pat_source[] = "_+";
1426 
1427  if (comp_pat0) return;
1428 
1429  comp_pat0 = rb_reg_new(comp_pat0_source, sizeof comp_pat0_source - 1, 0);
1430  rb_gc_register_mark_object(comp_pat0);
1431 
1432  comp_pat1 = rb_reg_new(comp_pat1_source, sizeof comp_pat1_source - 1, 0);
1433  rb_gc_register_mark_object(comp_pat1);
1434 
1435  comp_pat2 = rb_reg_new(comp_pat2_source, sizeof comp_pat2_source - 1, 0);
1436  rb_gc_register_mark_object(comp_pat2);
1437 
1438  a_slash = rb_usascii_str_new2("/");
1439  rb_gc_register_mark_object(a_slash);
1440 
1441  a_dot_and_an_e = rb_usascii_str_new2(".eE");
1442  rb_gc_register_mark_object(a_dot_and_an_e);
1443 
1444  null_string = rb_usascii_str_new2("");
1445  rb_gc_register_mark_object(null_string);
1446 
1447  underscores_pat = rb_reg_new(underscores_pat_source,
1448  sizeof underscores_pat_source - 1, 0);
1449  rb_gc_register_mark_object(underscores_pat);
1450 
1451  an_underscore = rb_usascii_str_new2("_");
1452  rb_gc_register_mark_object(an_underscore);
1453 }
1454 
1455 #define id_match rb_intern("match")
1456 #define f_match(x,y) rb_funcall((x), id_match, 1, (y))
1457 
1458 #define id_gsub_bang rb_intern("gsub!")
1459 #define f_gsub_bang(x,y,z) rb_funcall((x), id_gsub_bang, 2, (y), (z))
1460 
1461 static VALUE
1463 {
1464  VALUE s;
1465 
1466  s = self;
1467 
1468  if (RSTRING_LEN(s) == 0)
1469  return rb_assoc_new(Qnil, self);
1470 
1471  {
1472  VALUE m, sr, si, re, r, i;
1473  int po;
1474 
1475  m = f_match(comp_pat0, s);
1476  if (!NIL_P(m)) {
1477  sr = rb_reg_nth_match(1, m);
1478  si = rb_reg_nth_match(2, m);
1479  re = rb_reg_match_post(m);
1480  po = 1;
1481  }
1482  if (NIL_P(m)) {
1483  m = f_match(comp_pat1, s);
1484  if (!NIL_P(m)) {
1485  sr = Qnil;
1486  si = rb_reg_nth_match(1, m);
1487  if (NIL_P(si))
1488  si = rb_usascii_str_new2("");
1489  {
1490  VALUE t;
1491 
1492  t = rb_reg_nth_match(2, m);
1493  if (NIL_P(t))
1494  t = rb_usascii_str_new2("1");
1495  rb_str_concat(si, t);
1496  }
1497  re = rb_reg_match_post(m);
1498  po = 0;
1499  }
1500  }
1501  if (NIL_P(m)) {
1502  m = f_match(comp_pat2, s);
1503  if (NIL_P(m))
1504  return rb_assoc_new(Qnil, self);
1505  sr = rb_reg_nth_match(1, m);
1506  if (NIL_P(rb_reg_nth_match(2, m)))
1507  si = Qnil;
1508  else {
1509  VALUE t;
1510 
1511  si = rb_reg_nth_match(3, m);
1512  t = rb_reg_nth_match(4, m);
1513  if (NIL_P(t))
1514  t = rb_usascii_str_new2("1");
1515  rb_str_concat(si, t);
1516  }
1517  re = rb_reg_match_post(m);
1518  po = 0;
1519  }
1520  r = INT2FIX(0);
1521  i = INT2FIX(0);
1522  if (!NIL_P(sr)) {
1523  if (strchr(RSTRING_PTR(sr), '/'))
1524  r = f_to_r(sr);
1525  else if (strpbrk(RSTRING_PTR(sr), ".eE"))
1526  r = f_to_f(sr);
1527  else
1528  r = f_to_i(sr);
1529  }
1530  if (!NIL_P(si)) {
1531  if (strchr(RSTRING_PTR(si), '/'))
1532  i = f_to_r(si);
1533  else if (strpbrk(RSTRING_PTR(si), ".eE"))
1534  i = f_to_f(si);
1535  else
1536  i = f_to_i(si);
1537  }
1538  if (po)
1539  return rb_assoc_new(rb_complex_polar(r, i), re);
1540  else
1541  return rb_assoc_new(rb_complex_new2(r, i), re);
1542  }
1543 }
1544 
1545 static VALUE
1547 {
1548  VALUE a = string_to_c_internal(self);
1549  if (NIL_P(RARRAY_PTR(a)[0]) || RSTRING_LEN(RARRAY_PTR(a)[1]) > 0) {
1550  VALUE s = f_inspect(self);
1551  rb_raise(rb_eArgError, "invalid value for convert(): %s",
1552  StringValuePtr(s));
1553  }
1554  return RARRAY_PTR(a)[0];
1555 }
1556 
1557 #define id_gsub rb_intern("gsub")
1558 #define f_gsub(x,y,z) rb_funcall((x), id_gsub, 2, (y), (z))
1559 
1560 /*
1561  * call-seq:
1562  * str.to_c -> complex
1563  *
1564  * Returns a complex which denotes the string form. The parser
1565  * ignores leading whitespaces and trailing garbage. Any digit
1566  * sequences can be separated by an underscore. Returns zero for null
1567  * or garbage string.
1568  *
1569  * For example:
1570  *
1571  * '9'.to_c #=> (9+0i)
1572  * '2.5'.to_c #=> (2.5+0i)
1573  * '2.5/1'.to_c #=> ((5/2)+0i)
1574  * '-3/2'.to_c #=> ((-3/2)+0i)
1575  * '-i'.to_c #=> (0-1i)
1576  * '45i'.to_c #=> (0+45i)
1577  * '3-4i'.to_c #=> (3-4i)
1578  * '-4e2-4e-2i'.to_c #=> (-400.0-0.04i)
1579  * '-0.0-0.0i'.to_c #=> (-0.0-0.0i)
1580  * '1/2+3/4i'.to_c #=> ((1/2)+(3/4)*i)
1581  * 'ruby'.to_c #=> (0+0i)
1582  */
1583 static VALUE
1585 {
1586  VALUE s, a, backref;
1587 
1588  backref = rb_backref_get();
1589  rb_match_busy(backref);
1590 
1591  s = f_gsub(self, underscores_pat, an_underscore);
1592  a = string_to_c_internal(s);
1593 
1594  rb_backref_set(backref);
1595 
1596  if (!NIL_P(RARRAY_PTR(a)[0]))
1597  return RARRAY_PTR(a)[0];
1598  return rb_complex_new1(INT2FIX(0));
1599 }
1600 
1601 static VALUE
1602 nucomp_s_convert(int argc, VALUE *argv, VALUE klass)
1603 {
1604  VALUE a1, a2, backref;
1605 
1606  rb_scan_args(argc, argv, "11", &a1, &a2);
1607 
1608  if (NIL_P(a1) || (argc == 2 && NIL_P(a2)))
1609  rb_raise(rb_eTypeError, "can't convert nil into Complex");
1610 
1611  backref = rb_backref_get();
1612  rb_match_busy(backref);
1613 
1614  switch (TYPE(a1)) {
1615  case T_FIXNUM:
1616  case T_BIGNUM:
1617  case T_FLOAT:
1618  break;
1619  case T_STRING:
1620  a1 = string_to_c_strict(a1);
1621  break;
1622  }
1623 
1624  switch (TYPE(a2)) {
1625  case T_FIXNUM:
1626  case T_BIGNUM:
1627  case T_FLOAT:
1628  break;
1629  case T_STRING:
1630  a2 = string_to_c_strict(a2);
1631  break;
1632  }
1633 
1634  rb_backref_set(backref);
1635 
1636  switch (TYPE(a1)) {
1637  case T_COMPLEX:
1638  {
1639  get_dat1(a1);
1640 
1641  if (k_exact_zero_p(dat->imag))
1642  a1 = dat->real;
1643  }
1644  }
1645 
1646  switch (TYPE(a2)) {
1647  case T_COMPLEX:
1648  {
1649  get_dat1(a2);
1650 
1651  if (k_exact_zero_p(dat->imag))
1652  a2 = dat->real;
1653  }
1654  }
1655 
1656  switch (TYPE(a1)) {
1657  case T_COMPLEX:
1658  if (argc == 1 || (k_exact_zero_p(a2)))
1659  return a1;
1660  }
1661 
1662  if (argc == 1) {
1663  if (k_numeric_p(a1) && !f_real_p(a1))
1664  return a1;
1665  /* should raise exception for consistency */
1666  if (!k_numeric_p(a1))
1667  return rb_convert_type(a1, T_COMPLEX, "Complex", "to_c");
1668  }
1669  else {
1670  if ((k_numeric_p(a1) && k_numeric_p(a2)) &&
1671  (!f_real_p(a1) || !f_real_p(a2)))
1672  return f_add(a1,
1673  f_mul(a2,
1675  }
1676 
1677  {
1678  VALUE argv2[2];
1679  argv2[0] = a1;
1680  argv2[1] = a2;
1681  return nucomp_s_new(argc, argv2, klass);
1682  }
1683 }
1684 
1685 /* --- */
1686 
1687 /*
1688  * call-seq:
1689  * num.real -> self
1690  *
1691  * Returns self.
1692  */
1693 static VALUE
1695 {
1696  return self;
1697 }
1698 
1699 /*
1700  * call-seq:
1701  * num.imag -> 0
1702  * num.imaginary -> 0
1703  *
1704  * Returns zero.
1705  */
1706 static VALUE
1708 {
1709  return INT2FIX(0);
1710 }
1711 
1712 /*
1713  * call-seq:
1714  * num.abs2 -> real
1715  *
1716  * Returns square of self.
1717  */
1718 static VALUE
1720 {
1721  return f_mul(self, self);
1722 }
1723 
1724 #define id_PI rb_intern("PI")
1725 
1726 /*
1727  * call-seq:
1728  * num.arg -> 0 or float
1729  * num.angle -> 0 or float
1730  * num.phase -> 0 or float
1731  *
1732  * Returns 0 if the value is positive, pi otherwise.
1733  */
1734 static VALUE
1736 {
1737  if (f_positive_p(self))
1738  return INT2FIX(0);
1739  return rb_const_get(rb_mMath, id_PI);
1740 }
1741 
1742 /*
1743  * call-seq:
1744  * num.rect -> array
1745  *
1746  * Returns an array; [num, 0].
1747  */
1748 static VALUE
1750 {
1751  return rb_assoc_new(self, INT2FIX(0));
1752 }
1753 
1754 /*
1755  * call-seq:
1756  * num.polar -> array
1757  *
1758  * Returns an array; [num.abs, num.arg].
1759  */
1760 static VALUE
1762 {
1763  return rb_assoc_new(f_abs(self), f_arg(self));
1764 }
1765 
1766 /*
1767  * call-seq:
1768  * num.conj -> self
1769  * num.conjugate -> self
1770  *
1771  * Returns self.
1772  */
1773 static VALUE
1775 {
1776  return self;
1777 }
1778 
1779 /*
1780  * call-seq:
1781  * flo.arg -> 0 or float
1782  * flo.angle -> 0 or float
1783  * flo.phase -> 0 or float
1784  *
1785  * Returns 0 if the value is positive, pi otherwise.
1786  */
1787 static VALUE
1789 {
1790  if (isnan(RFLOAT_VALUE(self)))
1791  return self;
1792  if (f_tpositive_p(self))
1793  return INT2FIX(0);
1794  return rb_const_get(rb_mMath, id_PI);
1795 }
1796 
1797 /*
1798  * A complex number can be represented as a paired real number with
1799  * imaginary unit; a+bi. Where a is real part, b is imaginary part
1800  * and i is imaginary unit. Real a equals complex a+0i
1801  * mathematically.
1802  *
1803  * In ruby, you can create complex object with Complex, Complex::rect,
1804  * Complex::polar or to_c method.
1805  *
1806  * Complex(1) #=> (1+0i)
1807  * Complex(2, 3) #=> (2+3i)
1808  * Complex.polar(2, 3) #=> (-1.9799849932008908+0.2822400161197344i)
1809  * 3.to_c #=> (3+0i)
1810  *
1811  * You can also create complex object from floating-point numbers or
1812  * strings.
1813  *
1814  * Complex(0.3) #=> (0.3+0i)
1815  * Complex('0.3-0.5i') #=> (0.3-0.5i)
1816  * Complex('2/3+3/4i') #=> ((2/3)+(3/4)*i)
1817  * Complex('1@2') #=> (-0.4161468365471424+0.9092974268256817i)
1818  *
1819  * 0.3.to_c #=> (0.3+0i)
1820  * '0.3-0.5i'.to_c #=> (0.3-0.5i)
1821  * '2/3+3/4i'.to_c #=> ((2/3)+(3/4)*i)
1822  * '1@2'.to_c #=> (-0.4161468365471424+0.9092974268256817i)
1823  *
1824  * A complex object is either an exact or an inexact number.
1825  *
1826  * Complex(1, 1) / 2 #=> ((1/2)+(1/2)*i)
1827  * Complex(1, 1) / 2.0 #=> (0.5+0.5i)
1828  */
1829 void
1831 {
1832 #undef rb_intern
1833 #define rb_intern(str) rb_intern_const(str)
1834 
1835  assert(fprintf(stderr, "assert() is now active\n"));
1836 
1837  id_abs = rb_intern("abs");
1838  id_abs2 = rb_intern("abs2");
1839  id_arg = rb_intern("arg");
1840  id_cmp = rb_intern("<=>");
1841  id_conj = rb_intern("conj");
1842  id_convert = rb_intern("convert");
1843  id_denominator = rb_intern("denominator");
1844  id_divmod = rb_intern("divmod");
1845  id_eqeq_p = rb_intern("==");
1846  id_expt = rb_intern("**");
1847  id_fdiv = rb_intern("fdiv");
1848  id_floor = rb_intern("floor");
1849  id_idiv = rb_intern("div");
1850  id_imag = rb_intern("imag");
1851  id_inspect = rb_intern("inspect");
1852  id_negate = rb_intern("-@");
1853  id_numerator = rb_intern("numerator");
1854  id_quo = rb_intern("quo");
1855  id_real = rb_intern("real");
1856  id_real_p = rb_intern("real?");
1857  id_to_f = rb_intern("to_f");
1858  id_to_i = rb_intern("to_i");
1859  id_to_r = rb_intern("to_r");
1860  id_to_s = rb_intern("to_s");
1861 
1862  rb_cComplex = rb_define_class("Complex", rb_cNumeric);
1863 
1865  rb_undef_method(CLASS_OF(rb_cComplex), "allocate");
1866 
1867 #if 0
1868  rb_define_private_method(CLASS_OF(rb_cComplex), "new!", nucomp_s_new_bang, -1);
1870 #else
1872 #endif
1873 
1877 
1879 
1883  rb_undef_method(rb_cComplex, "<=>");
1886  rb_undef_method(rb_cComplex, "between?");
1887  rb_undef_method(rb_cComplex, "div");
1888  rb_undef_method(rb_cComplex, "divmod");
1889  rb_undef_method(rb_cComplex, "floor");
1890  rb_undef_method(rb_cComplex, "ceil");
1891  rb_undef_method(rb_cComplex, "modulo");
1892  rb_undef_method(rb_cComplex, "remainder");
1893  rb_undef_method(rb_cComplex, "round");
1894  rb_undef_method(rb_cComplex, "step");
1895  rb_undef_method(rb_cComplex, "truncate");
1897 
1898 #if 0 /* NUBY */
1900 #endif
1901 
1903  rb_define_method(rb_cComplex, "imaginary", nucomp_imag, 0);
1905 
1914 
1917 
1919  rb_define_method(rb_cComplex, "magnitude", nucomp_abs, 0);
1922  rb_define_method(rb_cComplex, "angle", nucomp_arg, 0);
1923  rb_define_method(rb_cComplex, "phase", nucomp_arg, 0);
1924  rb_define_method(rb_cComplex, "rectangular", nucomp_rect, 0);
1927  rb_define_method(rb_cComplex, "conjugate", nucomp_conj, 0);
1929 #if 0
1930  rb_define_method(rb_cComplex, "~", nucomp_conj, 0); /* gcc */
1931 #endif
1932 
1934 #if 0
1935  rb_define_method(rb_cComplex, "complex?", nucomp_true, 0);
1936  rb_define_method(rb_cComplex, "exact?", nucomp_exact_p, 0);
1937  rb_define_method(rb_cComplex, "inexact?", nucomp_inexact_p, 0);
1938 #endif
1939 
1940  rb_define_method(rb_cComplex, "numerator", nucomp_numerator, 0);
1941  rb_define_method(rb_cComplex, "denominator", nucomp_denominator, 0);
1942 
1945 
1948 
1949  rb_define_method(rb_cComplex, "marshal_dump", nucomp_marshal_dump, 0);
1950  rb_define_method(rb_cComplex, "marshal_load", nucomp_marshal_load, 1);
1951 
1952  /* --- */
1953 
1957  rb_define_method(rb_cComplex, "rationalize", nucomp_rationalize, -1);
1960 
1961  make_patterns();
1962 
1964 
1966 
1967  /* --- */
1968 
1970  rb_define_method(rb_cNumeric, "imaginary", numeric_imag, 0);
1976  rb_define_method(rb_cNumeric, "rectangular", numeric_rect, 0);
1979  rb_define_method(rb_cNumeric, "conjugate", numeric_conj, 0);
1981 
1982  rb_define_method(rb_cFloat, "arg", float_arg, 0);
1983  rb_define_method(rb_cFloat, "angle", float_arg, 0);
1984  rb_define_method(rb_cFloat, "phase", float_arg, 0);
1985 
1988 }
1989 
1990 /*
1991 Local variables:
1992 c-file-style: "ruby"
1993 End:
1994 */
RUBY_EXTERN VALUE rb_cString
Definition: ruby.h:1276
static VALUE nucomp_expt(VALUE self, VALUE other)
Definition: complex.c:840
#define RSTRING_LEN(string)
Definition: generator.h:45
static long NUM2LONG(VALUE x)
Definition: ruby.h:510
#define ZERO
Definition: complex.c:15
VALUE rb_hash(VALUE obj)
Definition: hash.c:60
static VALUE nucomp_rationalize(int argc, VALUE *argv, VALUE self)
Definition: complex.c:1368
RUBY_EXTERN VALUE rb_cFloat
Definition: ruby.h:1259
VALUE rb_num_coerce_bin(VALUE, VALUE, ID)
Definition: numeric.c:220
double sinh(double x)
Definition: math.c:204
#define fun1(n)
Definition: complex.c:35
#define binop(n, op)
Definition: complex.c:28
int i
Definition: win32ole.c:776
void rb_backref_set(VALUE)
Definition: vm.c:749
#define T_FIXNUM
Definition: ruby.h:425
static VALUE nucomp_to_f(VALUE self)
Definition: complex.c:1328
static VALUE nucomp_denominator(VALUE self)
Definition: complex.c:1101
#define nucomp_quo
Definition: complex.c:804
RUBY_EXTERN int signbit(double x)
Definition: signbit.c:5
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1343
#define k_inexact_p(x)
Definition: complex.c:298
static VALUE nilclass_to_c(VALUE self)
Definition: complex.c:1389
static ID id_to_r
Definition: complex.c:21
static VALUE nucomp_sub(VALUE self, VALUE other)
Definition: complex.c:696
#define CLASS_OF(v)
Definition: ruby.h:376
static VALUE nucomp_imag(VALUE self)
Definition: complex.c:634
#define Qtrue
Definition: ruby.h:366
#define fun2(n)
Definition: complex.c:42
static VALUE f_complex_new2(VALUE klass, VALUE x, VALUE y)
Definition: complex.c:470
#define RFLOAT_VALUE(val)
Definition: generator.h:32
static VALUE f_signbit(VALUE x)
Definition: complex.c:1174
static VALUE comp_pat2
Definition: complex.c:1406
static VALUE f_lt_p(VALUE x, VALUE y)
Definition: complex.c:108
VALUE rb_complex_polar(VALUE x, VALUE y)
Definition: complex.c:1286
static VALUE k_numeric_p(VALUE x)
Definition: complex.c:256
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1222
static VALUE nucomp_s_new(int argc, VALUE *argv, VALUE klass)
Definition: complex.c:444
VALUE rb_eTypeError
Definition: error.c:467
#define T_RATIONAL
Definition: ruby.h:431
VALUE rb_str_concat(VALUE, VALUE)
Definition: string.c:2088
st_index_t rb_memhash(const void *ptr, long len)
Definition: random.c:1336
#define id_PI
Definition: complex.c:1724
static VALUE nucomp_add(VALUE self, VALUE other)
Definition: complex.c:684
VALUE rb_lcm(VALUE x, VALUE y)
Definition: rational.c:1668
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:638
static VALUE string_to_c_strict(VALUE self)
Definition: complex.c:1546
static VALUE k_bignum_p(VALUE x)
Definition: complex.c:274
static ID id_to_i
Definition: complex.c:21
#define RSTRING_PTR(string)
Definition: generator.h:42
static VALUE nucomp_to_s(VALUE self)
Definition: complex.c:1222
VALUE rb_backref_get(void)
Definition: vm.c:743
#define Check_Type(v, t)
Definition: ruby.h:459
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1574
VALUE rb_convert_type(VALUE, int, const char *, const char *)
Definition: object.c:2079
static VALUE f_complex_polar(VALUE klass, VALUE x, VALUE y)
Definition: complex.c:575
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Definition: object.c:525
void Init_Complex(void)
Definition: complex.c:1830
static VALUE nucomp_abs(VALUE self)
Definition: complex.c:963
#define RARRAY_LEN(ARRAY)
Definition: generator.h:39
static VALUE nucomp_negate(VALUE self)
Definition: complex.c:647
static VALUE nucomp_mul(VALUE self, VALUE other)
Definition: complex.c:708
#define T_ARRAY
Definition: ruby.h:420
st_data_t st_index_t
Definition: st.h:63
double cosh(double x)
Definition: math.c:181
double rb_str_to_dbl(VALUE, int)
Definition: object.c:2324
VALUE rb_reg_match_post(VALUE)
Definition: re.c:1516
void rb_define_global_function(const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a global function.
Definition: class.c:1372
RUBY_EXTERN VALUE rb_mMath
Definition: ruby.h:1240
int rb_isdigit(int c)
Definition: encoding.c:1642
static VALUE m_sin(VALUE x)
Definition: complex.c:536
#define FIXNUM_P(f)
Definition: ruby.h:338
static VALUE f_negative_p(VALUE x)
Definition: date_core.c:124
static VALUE a_slash
Definition: complex.c:1406
static VALUE nucomp_arg(VALUE self)
Definition: complex.c:1008
void rb_undef_method(VALUE klass, const char *name)
Definition: class.c:1228
static VALUE nucomp_inspect(VALUE self)
Definition: complex.c:1234
Definition: ruby.h:755
static ID id_floor
Definition: complex.c:21
static ID id_denominator
Definition: complex.c:21
static VALUE k_float_p(VALUE x)
Definition: complex.c:280
#define rb_complex_new1(x)
Definition: intern.h:163
#define m_hypot(x, y)
static VALUE k_complex_p(VALUE x)
Definition: complex.c:292
VALUE rb_eRangeError
Definition: error.c:471
const char * rb_obj_classname(VALUE)
Definition: variable.c:318
static VALUE f_add(VALUE x, VALUE y)
Definition: complex.c:66
static VALUE numeric_rect(VALUE self)
Definition: complex.c:1749
#define PATTERN1
Definition: complex.c:1416
static VALUE nucomp_eqeq_p(VALUE self, VALUE other)
Definition: complex.c:925
#define k_exact_p(x)
Definition: complex.c:297
static ID id_inspect
Definition: complex.c:21
#define RRATIONAL(obj)
Definition: ruby.h:918
VALUE rb_math_log(int argc, VALUE *argv)
static VALUE numeric_abs2(VALUE self)
Definition: complex.c:1719
static ID id_quo
Definition: complex.c:21
static VALUE nucomp_eql_p(VALUE self, VALUE other)
Definition: complex.c:1160
#define get_dat1(x)
Definition: complex.c:303
#define f_to_i(x)
Definition: date_core.c:42
static VALUE comp_pat0
Definition: complex.c:1406
static ID id_imag
Definition: complex.c:21
static VALUE f_complex_new_bang1(VALUE klass, VALUE x)
Definition: complex.c:355
static ID id_convert
Definition: complex.c:21
VALUE rb_str_to_inum(VALUE str, int base, int badcheck)
Definition: bignum.c:765
static VALUE nucomp_f_complex(int argc, VALUE *argv, VALUE klass)
Definition: complex.c:483
VALUE rb_str_cat2(VALUE, const char *)
Definition: string.c:1908
static VALUE nucomp_real(VALUE self)
Definition: complex.c:620
static VALUE string_to_c(VALUE self)
Definition: complex.c:1584
#define NIL_P(v)
Definition: ruby.h:374
static VALUE numeric_conj(VALUE self)
Definition: complex.c:1774
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:469
static VALUE nucomp_s_alloc(VALUE klass)
Definition: complex.c:325
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:1923
static void make_patterns(void)
Definition: complex.c:1420
static VALUE an_underscore
Definition: complex.c:1406
#define k_exact_zero_p(x)
Definition: complex.c:300
static VALUE float_arg(VALUE self)
Definition: complex.c:1788
#define NEWOBJ(obj, type)
Definition: ruby.h:580
#define T_FLOAT
Definition: ruby.h:417
static VALUE f_tpositive_p(VALUE x)
Definition: complex.c:1190
#define TYPE(x)
Definition: ruby.h:441
static ID id_expt
Definition: complex.c:21
int argc
Definition: ruby.c:120
#define Qfalse
Definition: ruby.h:365
static VALUE f_sub(VALUE x, VALUE y)
Definition: complex.c:144
#define T_BIGNUM
Definition: ruby.h:423
void rb_gc_register_mark_object(VALUE obj)
Definition: gc.c:971
static VALUE comp_pat1
Definition: complex.c:1406
#define RUBY_FUNC_EXPORTED
Definition: defines.h:254
static ID id_numerator
Definition: complex.c:21
arg
Definition: ripper.y:1287
#define T_COMPLEX
Definition: ruby.h:432
static VALUE nucomp_fdiv(VALUE self, VALUE other)
Definition: complex.c:817
#define PATTERN2
Definition: complex.c:1417
#define f_denominator(x)
Definition: rational.c:1720
#define f_mul(x, y)
Definition: date_core.c:30
#define f_positive_p(x)
Definition: complex.c:207
VALUE rb_const_get(VALUE, ID)
Definition: variable.c:1635
#define f_inspect(x)
Definition: date_core.c:45
#define imp1(n)
Definition: complex.c:488
#define PATTERN0
Definition: complex.c:1415
static VALUE a_dot_and_an_e
Definition: complex.c:1406
VALUE rb_reg_new(const char *, long, int)
Definition: re.c:2510
SSL_METHOD *(* func)(void)
Definition: ossl_ssl.c:104
#define rb_complex_new2(x, y)
Definition: intern.h:164
static ID id_abs2
Definition: complex.c:21
static VALUE numeric_arg(VALUE self)
Definition: complex.c:1735
static VALUE f_addsub(VALUE self, VALUE other, VALUE(*func)(VALUE, VALUE), ID id)
Definition: complex.c:655
#define f_to_s(x)
Definition: date_core.c:44
static ID id_real
Definition: complex.c:21
VALUE rb_funcall2(VALUE, ID, int, const VALUE *)
Calls a method.
Definition: vm_eval.c:669
static ID id_idiv
Definition: complex.c:21
static VALUE nucomp_to_r(VALUE self)
Definition: complex.c:1348
static VALUE f_cmp(VALUE x, VALUE y)
Definition: complex.c:78
static VALUE f_zero_p(VALUE x)
Definition: complex.c:210
static VALUE f_to_f(VALUE x)
Definition: complex.c:174
static ID id_arg
Definition: complex.c:21
RUBY_EXTERN double hypot(double, double)
Definition: hypot.c:6
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1416
static VALUE f_div(VALUE x, VALUE y)
Definition: complex.c:92
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Definition: array.c:460
unsigned long ID
Definition: ruby.h:89
#define Qnil
Definition: ruby.h:367
unsigned long VALUE
Definition: ruby.h:88
char * strchr(char *, char)
RUBY_EXTERN VALUE rb_cInteger
Definition: ruby.h:1261
void rb_match_busy(VALUE)
Definition: re.c:1177
#define RARRAY_PTR(ARRAY)
Definition: generator.h:36
VALUE rb_Complex(VALUE x, VALUE y)
Definition: complex.c:1294
#define isnan(x)
Definition: win32.h:334
static VALUE nucomp_s_polar(int argc, VALUE *argv, VALUE klass)
Definition: complex.c:596
RUBY_EXTERN VALUE rb_cNumeric
Definition: ruby.h:1268
VALUE rb_complex_new(VALUE x, VALUE y)
Definition: complex.c:1280
static void nucomp_real_check(VALUE num)
Definition: complex.c:384
static VALUE numeric_to_c(VALUE self)
Definition: complex.c:1401
#define ONE
Definition: complex.c:16
static VALUE nucomp_numerator(VALUE self)
Definition: complex.c:1128
VALUE rb_usascii_str_new2(const char *)
static VALUE nucomp_s_canonicalize_internal(VALUE klass, VALUE real, VALUE imag)
Definition: complex.c:399
#define quo(x, y)
void nucomp_canonicalization(int)
static VALUE nucomp_abs2(VALUE self)
Definition: complex.c:989
static ID id_eqeq_p
Definition: complex.c:21
#define INT2FIX(i)
Definition: ruby.h:225
VALUE rb_cBignum
Definition: bignum.c:27
#define f_quo(x, y)
Definition: date_core.c:32
static VALUE f_kind_of_p(VALUE x, VALUE c)
Definition: complex.c:250
static VALUE nucomp_to_i(VALUE self)
Definition: complex.c:1309
static VALUE k_fixnum_p(VALUE x)
Definition: complex.c:268
#define rb_intern(str)
#define f_expt(x, y)
Definition: date_core.c:36
static ID id_fdiv
Definition: complex.c:21
static ID id_conj
Definition: complex.c:21
static VALUE f_complex_new1(VALUE klass, VALUE x)
Definition: complex.c:463
VALUE rb_complex_raw(VALUE x, VALUE y)
Definition: complex.c:1274
static VALUE k_integer_p(VALUE x)
Definition: complex.c:262
static ID id_negate
Definition: complex.c:21
#define LONG2FIX(i)
Definition: ruby.h:226
#define T_STRING
Definition: ruby.h:418
#define f_boolcast(x)
Definition: complex.c:26
static VALUE f_eqeq_p(VALUE x, VALUE y)
Definition: date_core.c:97
#define get_dat2(x, y)
Definition: complex.c:307
#define f_nonzero_p(x)
Definition: complex.c:227
static VALUE k_rational_p(VALUE x)
Definition: complex.c:286
static VALUE nucomp_rect(VALUE self)
Definition: complex.c:1022
static VALUE nucomp_marshal_load(VALUE self, VALUE a)
Definition: complex.c:1259
v
Definition: win32ole.c:790
static VALUE f_divide(VALUE self, VALUE other, VALUE(*func)(VALUE, VALUE), ID id)
Definition: complex.c:733
static VALUE nucomp_s_new_internal(VALUE klass, VALUE real, VALUE imag)
Definition: complex.c:313
#define TWO
Definition: complex.c:17
static VALUE string_to_c_internal(VALUE self)
Definition: complex.c:1462
static VALUE numeric_imag(VALUE self)
Definition: complex.c:1707
static VALUE nucomp_hash(VALUE self)
Definition: complex.c:1144
static VALUE nucomp_conj(VALUE self)
Definition: complex.c:1048
#define f_gsub(x, y, z)
Definition: complex.c:1558
static VALUE nucomp_s_convert(int argc, VALUE *argv, VALUE klass)
Definition: complex.c:1602
static VALUE null_string
Definition: complex.c:1406
RUBY_EXTERN VALUE rb_cRational
Definition: ruby.h:1272
#define assert(condition)
Definition: ossl.h:44
static ID id_cmp
Definition: complex.c:21
static VALUE f_complex_new_bang2(VALUE klass, VALUE x, VALUE y)
Definition: complex.c:362
#define StringValuePtr(v)
Definition: ruby.h:467
static ID id_to_f
Definition: complex.c:21
static VALUE nucomp_coerce(VALUE self, VALUE other)
Definition: complex.c:943
#define f_numerator(x)
Definition: rational.c:1717
#define imp2(n)
Definition: complex.c:495
#define f_to_r(x)
Definition: date_core.c:43
static VALUE numeric_polar(VALUE self)
Definition: complex.c:1761
void rb_copy_generic_ivar(VALUE, VALUE)
Definition: variable.c:959
#define f_abs(x)
Definition: date_core.c:26
static VALUE nucomp_marshal_dump(VALUE self)
Definition: complex.c:1247
#define f_negate(x)
Definition: date_core.c:27
static VALUE f_reciprocal(VALUE x)
Definition: complex.c:823
#define f_match(x, y)
Definition: complex.c:1456
static ID id_divmod
Definition: complex.c:21
static VALUE f_gt_p(VALUE x, VALUE y)
Definition: complex.c:100
#define mod(x, y)
#define NULL
Definition: _sdbm.c:107
static VALUE underscores_pat
Definition: complex.c:1406
#define FIX2LONG(x)
Definition: ruby.h:336
static ID id_to_s
Definition: complex.c:21
RUBY_EXTERN VALUE rb_cFixnum
Definition: ruby.h:1258
#define OBJSETUP(obj, c, t)
Definition: ruby.h:581
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1210
void rb_warn(const char *fmt,...)
Definition: error.c:196
RUBY_EXTERN VALUE rb_cNilClass
Definition: ruby.h:1267
static ID id_abs
Definition: complex.c:21
VALUE rb_eArgError
Definition: error.c:468
static VALUE nucomp_false(VALUE self)
Definition: complex.c:1070
static VALUE numeric_real(VALUE self)
Definition: complex.c:1694
static VALUE nucomp_div(VALUE self, VALUE other)
Definition: complex.c:799
static VALUE nucomp_polar(VALUE self)
Definition: complex.c:1035
VALUE rb_reg_nth_match(int, VALUE)
Definition: re.c:1445
char ** argv
Definition: ruby.c:121
#define DBL2NUM(dbl)
Definition: ruby.h:647
static VALUE f_one_p(VALUE x)
Definition: complex.c:230
VALUE rb_cComplex
Definition: complex.c:19
static VALUE f_format(VALUE self, VALUE(*func)(VALUE))
Definition: complex.c:1196
static ID id_real_p
Definition: complex.c:21