/* * call-seq: * cmp.numerator -> numeric * * Returns the numerator. * * 1 2 3+4i <- numerator * - + -i -> ---- * 2 3 6 <- denominator * * c = Complex('1/2+2/3i') #=> ((1/2)+(2/3)*i) * n = c.numerator #=> (3+4i) * d = c.denominator #=> 6 * n / d #=> ((1/2)+(2/3)*i) * Complex(Rational(n.real, d), Rational(n.imag, d)) * #=> ((1/2)+(2/3)*i) * See denominator. */ static VALUE nucomp_numerator(VALUE self) { VALUE cd; get_dat1(self); cd = f_denominator(self); return f_complex_new2(CLASS_OF(self), f_mul(f_numerator(dat->real), f_div(cd, f_denominator(dat->real))), f_mul(f_numerator(dat->imag), f_div(cd, f_denominator(dat->imag)))); }
/* * call-seq: * cmp ** numeric -> complex * * Performs exponentiation. * * Complex('i') ** 2 #=> (-1+0i) * Complex(-8) ** Rational(1, 3) #=> (1.0000000000000002+1.7320508075688772i) */ static VALUE nucomp_expt(VALUE self, VALUE other) { if (k_numeric_p(other) && k_exact_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); /* c14n */ if (k_complex_p(other)) { get_dat1(other); if (k_exact_zero_p(dat->imag)) other = dat->real; /* c14n */ } if (k_complex_p(other)) { VALUE r, theta, nr, ntheta; get_dat1(other); r = f_abs(self); theta = f_arg(self); nr = m_exp_bang(f_sub(f_mul(dat->real, m_log_bang(r)), f_mul(dat->imag, theta))); ntheta = f_add(f_mul(theta, dat->real), f_mul(dat->imag, m_log_bang(r))); return f_complex_polar(CLASS_OF(self), nr, ntheta); } if (k_fixnum_p(other)) { if (f_gt_p(other, ZERO)) { VALUE x, z; long n; x = self; z = x; n = FIX2LONG(other) - 1; while (n) { long q, r; while (1) { get_dat1(x); q = n / 2; r = n % 2; if (r) break; x = nucomp_s_new_internal(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 = q; } z = f_mul(z, x); n--; } return z; } return f_expt(f_reciprocal(self), f_negate(other)); } if (k_numeric_p(other) && f_real_p(other)) { VALUE r, theta; if (k_bignum_p(other)) rb_warn("in a**b, b may be too big"); r = f_abs(self); theta = f_arg(self); return f_complex_polar(CLASS_OF(self), f_expt(r, other), f_mul(theta, other)); } return rb_num_coerce_bin(self, other, id_expt); }
/* * call-seq: * num.numerator -> integer * * Returns the numerator. */ static VALUE numeric_numerator(VALUE self, SEL sel) { return f_numerator(f_to_r(self)); }
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); }