static VALUE nurat_expt(VALUE self, VALUE other) { if (k_exact_p(other) && f_zero_p(other)) return f_rational_new_bang1(CLASS_OF(self), ONE); if (k_rational_p(other)) { get_dat1(other); if (f_one_p(dat->den)) other = dat->num; /* good? */ } switch (TYPE(other)) { case T_FIXNUM: case T_BIGNUM: { VALUE num, den; get_dat1(self); switch (FIX2INT(f_cmp(other, ZERO))) { case 1: num = f_expt(dat->num, other); den = f_expt(dat->den, other); break; case -1: num = f_expt(dat->den, f_negate(other)); den = f_expt(dat->num, f_negate(other)); break; default: num = ONE; den = ONE; break; } return f_rational_new2(CLASS_OF(self), num, den); } case T_FLOAT: case T_RATIONAL: return f_expt(f_to_f(self), other); default: return rb_num_coerce_bin(self, other, id_expt); } }
inline static VALUE nucomp_s_canonicalize_internal(VALUE klass, VALUE real, VALUE imag) { #ifdef CANON #define CL_CANON #ifdef CL_CANON if (f_zero_p(imag) && k_exact_p(imag) && canonicalization) return real; #else if (f_zero_p(imag) && canonicalization) return real; #endif #endif if (f_real_p(real) && f_real_p(imag)) return nucomp_s_new_internal(klass, real, imag); else if (f_real_p(real)) { get_dat1(imag); return nucomp_s_new_internal(klass, f_sub(real, dat->imag), f_add(ZERO, dat->real)); } else if (f_real_p(imag)) { get_dat1(real); return nucomp_s_new_internal(klass, dat->real, f_add(dat->imag, imag)); } else { get_dat2(real, imag); return nucomp_s_new_internal(klass, f_sub(adat->real, bdat->imag), f_add(adat->imag, bdat->real)); } }
/* :nodoc: */ static VALUE nucomp_exact_p(VALUE self) { get_dat1(self); return f_boolcast(k_exact_p(dat->real) && k_exact_p(dat->imag)); }
static VALUE nurat_s_convert(int argc, VALUE *argv, VALUE klass) { VALUE a1, a2, backref; rb_scan_args(argc, argv, "11", &a1, &a2); switch (TYPE(a1)) { case T_COMPLEX: if (k_exact_p(RCOMPLEX(a1)->imag) && f_zero_p(RCOMPLEX(a1)->imag)) a1 = RCOMPLEX(a1)->real; } switch (TYPE(a2)) { case T_COMPLEX: if (k_exact_p(RCOMPLEX(a2)->imag) && f_zero_p(RCOMPLEX(a2)->imag)) a2 = RCOMPLEX(a2)->real; } backref = rb_backref_get(); rb_match_busy(backref); switch (TYPE(a1)) { case T_FIXNUM: case T_BIGNUM: break; case T_FLOAT: a1 = f_to_r(a1); break; case T_STRING: a1 = string_to_r_strict(a1); break; } switch (TYPE(a2)) { case T_FIXNUM: case T_BIGNUM: break; case T_FLOAT: a2 = f_to_r(a2); break; case T_STRING: a2 = string_to_r_strict(a2); break; } rb_backref_set(backref); switch (TYPE(a1)) { case T_RATIONAL: if (argc == 1 || (k_exact_p(a2) && f_one_p(a2))) return a1; } if (argc == 1) { if (k_numeric_p(a1) && !f_integer_p(a1)) return a1; } else { if ((k_numeric_p(a1) && k_numeric_p(a2)) && (!f_integer_p(a1) || !f_integer_p(a2))) return f_div(a1, a2); } { VALUE argv2[2]; argv2[0] = a1; argv2[1] = a2; return nurat_s_new(argc, argv2, klass); } }
static VALUE nucomp_expt(VALUE self, VALUE other) { if (k_exact_p(other) && f_zero_p(other)) return f_complex_new_bang1(CLASS_OF(self), ONE); if (k_rational_p(other) && f_one_p(f_denominator(other))) other = f_numerator(other); /* good? */ if (k_complex_p(other)) { VALUE a, r, theta, ore, oim, nr, ntheta; get_dat1(other); a = f_polar(self); r = RARRAY_PTR(a)[0]; theta = RARRAY_PTR(a)[1]; ore = dat->real; oim = dat->imag; nr = m_exp_bang(f_sub(f_mul(ore, m_log_bang(r)), f_mul(oim, theta))); ntheta = f_add(f_mul(theta, ore), f_mul(oim, m_log_bang(r))); return f_complex_polar(CLASS_OF(self), nr, ntheta); } if (k_integer_p(other)) { if (f_gt_p(other, ZERO)) { VALUE x, z, n; x = self; z = x; n = f_sub(other, ONE); while (f_nonzero_p(n)) { VALUE a; while (a = f_divmod(n, TWO), f_zero_p(RARRAY_PTR(a)[1])) { get_dat1(x); x = f_complex_new2(CLASS_OF(self), f_sub(f_mul(dat->real, dat->real), f_mul(dat->imag, dat->imag)), f_mul(f_mul(TWO, dat->real), dat->imag)); n = RARRAY_PTR(a)[0]; } z = f_mul(z, x); n = f_sub(n, ONE); } return z; } return f_expt(f_div(f_to_r(ONE), self), f_negate(other)); } if (k_numeric_p(other) && f_real_p(other)) { VALUE a, r, theta; a = f_polar(self); r = RARRAY_PTR(a)[0]; theta = RARRAY_PTR(a)[1]; return f_complex_polar(CLASS_OF(self), f_expt(r, other), f_mul(theta, other)); } return rb_num_coerce_bin(self, other, id_expt); }
static VALUE nucomp_s_convert(int argc, VALUE *argv, VALUE klass) { VALUE a1, a2, backref; rb_scan_args(argc, argv, "11", &a1, &a2); backref = rb_backref_get(); rb_match_busy(backref); switch (TYPE(a1)) { case T_FIXNUM: case T_BIGNUM: case T_FLOAT: break; case T_STRING: a1 = string_to_c_strict(a1); break; } switch (TYPE(a2)) { case T_FIXNUM: case T_BIGNUM: case T_FLOAT: break; case T_STRING: a2 = string_to_c_strict(a2); break; } rb_backref_set(backref); switch (TYPE(a1)) { case T_COMPLEX: { get_dat1(a1); if (k_exact_p(dat->imag) && f_zero_p(dat->imag)) a1 = dat->real; } } switch (TYPE(a2)) { case T_COMPLEX: { get_dat1(a2); if (k_exact_p(dat->imag) && f_zero_p(dat->imag)) a2 = dat->real; } } switch (TYPE(a1)) { case T_COMPLEX: if (argc == 1 || (k_exact_p(a2) && f_zero_p(a2))) return a1; } if (argc == 1) { if (k_numeric_p(a1) && !f_real_p(a1)) return a1; } else { if ((k_numeric_p(a1) && k_numeric_p(a2)) && (!f_real_p(a1) || !f_real_p(a2))) return f_add(a1, f_mul(a2, f_complex_new_bang2(rb_cComplex, ZERO, ONE))); } { VALUE argv2[2]; argv2[0] = a1; argv2[1] = a2; return nucomp_s_new(argc, argv2, klass); } }