mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
complex.c: simplify division result
* complex.c (f_divide): canonicalize rationals to simplify integer complex results. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64610 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
9563db5eb1
commit
929e9713bb
4 changed files with 25 additions and 14 deletions
22
complex.c
22
complex.c
|
@ -774,6 +774,7 @@ f_divide(VALUE self, VALUE other,
|
||||||
VALUE (*func)(VALUE, VALUE), ID id)
|
VALUE (*func)(VALUE, VALUE), ID id)
|
||||||
{
|
{
|
||||||
if (RB_TYPE_P(other, T_COMPLEX)) {
|
if (RB_TYPE_P(other, T_COMPLEX)) {
|
||||||
|
VALUE r, n, x, y;
|
||||||
int flo;
|
int flo;
|
||||||
get_dat2(self, other);
|
get_dat2(self, other);
|
||||||
|
|
||||||
|
@ -781,35 +782,28 @@ f_divide(VALUE self, VALUE other,
|
||||||
RB_FLOAT_TYPE_P(bdat->real) || RB_FLOAT_TYPE_P(bdat->imag));
|
RB_FLOAT_TYPE_P(bdat->real) || RB_FLOAT_TYPE_P(bdat->imag));
|
||||||
|
|
||||||
if (f_gt_p(f_abs(bdat->real), f_abs(bdat->imag))) {
|
if (f_gt_p(f_abs(bdat->real), f_abs(bdat->imag))) {
|
||||||
VALUE r, n;
|
|
||||||
|
|
||||||
r = (*func)(bdat->imag, bdat->real);
|
r = (*func)(bdat->imag, bdat->real);
|
||||||
n = f_mul(bdat->real, f_add(ONE, f_mul(r, r)));
|
n = f_mul(bdat->real, f_add(ONE, f_mul(r, r)));
|
||||||
if (flo)
|
if (flo)
|
||||||
return f_complex_new2(CLASS_OF(self),
|
return f_complex_new2(CLASS_OF(self),
|
||||||
(*func)(self, n),
|
(*func)(self, n),
|
||||||
(*func)(f_negate(f_mul(self, r)), n));
|
(*func)(f_negate(f_mul(self, r)), n));
|
||||||
return f_complex_new2(CLASS_OF(self),
|
x = (*func)(f_add(adat->real, f_mul(adat->imag, r)), n);
|
||||||
(*func)(f_add(adat->real,
|
y = (*func)(f_sub(adat->imag, f_mul(adat->real, r)), n);
|
||||||
f_mul(adat->imag, r)), n),
|
|
||||||
(*func)(f_sub(adat->imag,
|
|
||||||
f_mul(adat->real, r)), n));
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
VALUE r, n;
|
|
||||||
|
|
||||||
r = (*func)(bdat->real, bdat->imag);
|
r = (*func)(bdat->real, bdat->imag);
|
||||||
n = f_mul(bdat->imag, f_add(ONE, f_mul(r, r)));
|
n = f_mul(bdat->imag, f_add(ONE, f_mul(r, r)));
|
||||||
if (flo)
|
if (flo)
|
||||||
return f_complex_new2(CLASS_OF(self),
|
return f_complex_new2(CLASS_OF(self),
|
||||||
(*func)(f_mul(self, r), n),
|
(*func)(f_mul(self, r), n),
|
||||||
(*func)(f_negate(self), n));
|
(*func)(f_negate(self), n));
|
||||||
return f_complex_new2(CLASS_OF(self),
|
x = (*func)(f_add(f_mul(adat->real, r), adat->imag), n);
|
||||||
(*func)(f_add(f_mul(adat->real, r),
|
y = (*func)(f_sub(f_mul(adat->imag, r), adat->real), n);
|
||||||
adat->imag), n),
|
|
||||||
(*func)(f_sub(f_mul(adat->imag, r),
|
|
||||||
adat->real), n));
|
|
||||||
}
|
}
|
||||||
|
x = rb_rational_canonicalize(x);
|
||||||
|
y = rb_rational_canonicalize(y);
|
||||||
|
return f_complex_new2(CLASS_OF(self), x, y);
|
||||||
}
|
}
|
||||||
if (k_numeric_p(other) && f_real_p(other)) {
|
if (k_numeric_p(other) && f_real_p(other)) {
|
||||||
get_dat1(self);
|
get_dat1(self);
|
||||||
|
|
|
@ -1729,6 +1729,7 @@ rb_pid_t rb_fork_ruby(int *status);
|
||||||
void rb_last_status_clear(void);
|
void rb_last_status_clear(void);
|
||||||
|
|
||||||
/* rational.c */
|
/* rational.c */
|
||||||
|
VALUE rb_rational_canonicalize(VALUE x);
|
||||||
VALUE rb_rational_uminus(VALUE self);
|
VALUE rb_rational_uminus(VALUE self);
|
||||||
VALUE rb_rational_plus(VALUE self, VALUE other);
|
VALUE rb_rational_plus(VALUE self, VALUE other);
|
||||||
VALUE rb_lcm(VALUE x, VALUE y);
|
VALUE rb_lcm(VALUE x, VALUE y);
|
||||||
|
|
|
@ -1991,6 +1991,15 @@ rb_numeric_quo(VALUE x, VALUE y)
|
||||||
return nurat_div(x, y);
|
return nurat_div(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_rational_canonicalize(VALUE x)
|
||||||
|
{
|
||||||
|
if (RB_TYPE_P(x, T_RATIONAL)) {
|
||||||
|
get_dat1(x);
|
||||||
|
if (f_one_p(dat->den)) return dat->num;
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
|
|
|
@ -323,6 +323,13 @@ class Complex_Test < Test::Unit::TestCase
|
||||||
|
|
||||||
assert_equal(Complex(Rational(1,2),Rational(1)), c / Rational(2))
|
assert_equal(Complex(Rational(1,2),Rational(1)), c / Rational(2))
|
||||||
assert_equal(Complex(Rational(3,2),Rational(3)), c / Rational(2,3))
|
assert_equal(Complex(Rational(3,2),Rational(3)), c / Rational(2,3))
|
||||||
|
|
||||||
|
c = Complex(1)
|
||||||
|
r = c / c
|
||||||
|
assert_instance_of(Complex, r)
|
||||||
|
assert_equal(1, r)
|
||||||
|
assert_predicate(r.real, :integer?)
|
||||||
|
assert_predicate(r.imag, :integer?)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_quo
|
def test_quo
|
||||||
|
|
Loading…
Add table
Reference in a new issue