mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* complex.c (nucomp_addsub): new
* complex.c (nucomp_{add,sub}): use nucomp_addsub. * complex.c (nucomp_divide): changed the algorithm. * complex.c (nucomp_abs): added shortcuts. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@23872 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
f94228c8bd
commit
7cf1d66848
2 changed files with 82 additions and 45 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
Sat Jun 27 19:06:22 2009 Tadayoshi Funaba <tadf@dotrb.org>
|
||||
|
||||
* complex.c (nucomp_addsub): new
|
||||
|
||||
* complex.c (nucomp_{add,sub}): use nucomp_addsub.
|
||||
|
||||
* complex.c (nucomp_divide): changed the algorithm.
|
||||
|
||||
* complex.c (nucomp_abs): added shortcuts.
|
||||
|
||||
Sat Jun 27 16:56:33 2009 Tadayoshi Funaba <tadf@dotrb.org>
|
||||
|
||||
* rational.c (nurat_cmp): use rb_num_coerce_cmp.
|
||||
|
|
115
complex.c
115
complex.c
|
@ -585,6 +585,29 @@ nucomp_negate(VALUE self)
|
|||
f_negate(dat->real), f_negate(dat->imag));
|
||||
}
|
||||
|
||||
static VALUE
|
||||
nucomp_addsub(VALUE self, VALUE other,
|
||||
VALUE (*func)(VALUE, VALUE), ID id)
|
||||
{
|
||||
if (k_complex_p(other)) {
|
||||
VALUE real, imag;
|
||||
|
||||
get_dat2(self, other);
|
||||
|
||||
real = (*func)(adat->real, bdat->real);
|
||||
imag = (*func)(adat->imag, bdat->imag);
|
||||
|
||||
return f_complex_new2(CLASS_OF(self), real, imag);
|
||||
}
|
||||
if (k_numeric_p(other) && f_real_p(other)) {
|
||||
get_dat1(self);
|
||||
|
||||
return f_complex_new2(CLASS_OF(self),
|
||||
(*func)(dat->real, other), dat->imag);
|
||||
}
|
||||
return rb_num_coerce_bin(self, other, id);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* cmp + numeric -> complex
|
||||
|
@ -594,23 +617,7 @@ nucomp_negate(VALUE self)
|
|||
static VALUE
|
||||
nucomp_add(VALUE self, VALUE other)
|
||||
{
|
||||
if (k_complex_p(other)) {
|
||||
VALUE real, imag;
|
||||
|
||||
get_dat2(self, other);
|
||||
|
||||
real = f_add(adat->real, bdat->real);
|
||||
imag = f_add(adat->imag, bdat->imag);
|
||||
|
||||
return f_complex_new2(CLASS_OF(self), real, imag);
|
||||
}
|
||||
if (k_numeric_p(other) && f_real_p(other)) {
|
||||
get_dat1(self);
|
||||
|
||||
return f_complex_new2(CLASS_OF(self),
|
||||
f_add(dat->real, other), dat->imag);
|
||||
}
|
||||
return rb_num_coerce_bin(self, other, '+');
|
||||
return nucomp_addsub(self, other, f_add, '+');
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -622,23 +629,7 @@ nucomp_add(VALUE self, VALUE other)
|
|||
static VALUE
|
||||
nucomp_sub(VALUE self, VALUE other)
|
||||
{
|
||||
if (k_complex_p(other)) {
|
||||
VALUE real, imag;
|
||||
|
||||
get_dat2(self, other);
|
||||
|
||||
real = f_sub(adat->real, bdat->real);
|
||||
imag = f_sub(adat->imag, bdat->imag);
|
||||
|
||||
return f_complex_new2(CLASS_OF(self), real, imag);
|
||||
}
|
||||
if (k_numeric_p(other) && f_real_p(other)) {
|
||||
get_dat1(self);
|
||||
|
||||
return f_complex_new2(CLASS_OF(self),
|
||||
f_sub(dat->real, other), dat->imag);
|
||||
}
|
||||
return rb_num_coerce_bin(self, other, '-');
|
||||
return nucomp_addsub(self, other, f_sub, '-');
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -677,19 +668,42 @@ nucomp_divide(VALUE self, VALUE other,
|
|||
VALUE (*func)(VALUE, VALUE), ID id)
|
||||
{
|
||||
if (k_complex_p(other)) {
|
||||
int flo;
|
||||
get_dat2(self, other);
|
||||
|
||||
if (TYPE(adat->real) == T_FLOAT ||
|
||||
TYPE(adat->imag) == T_FLOAT ||
|
||||
TYPE(bdat->real) == T_FLOAT ||
|
||||
TYPE(bdat->imag) == T_FLOAT) {
|
||||
VALUE magn = m_hypot(bdat->real, bdat->imag);
|
||||
VALUE tmp = f_complex_new_bang2(CLASS_OF(self),
|
||||
(*func)(bdat->real, magn),
|
||||
(*func)(bdat->imag, magn));
|
||||
return (*func)(f_mul(self, f_conj(tmp)), magn);
|
||||
flo = (k_float_p(adat->real) || k_float_p(adat->imag) ||
|
||||
k_float_p(bdat->real) || k_float_p(bdat->imag));
|
||||
|
||||
if (f_gt_p(f_abs(bdat->real), f_abs(bdat->imag))) {
|
||||
VALUE r, n;
|
||||
|
||||
r = (*func)(bdat->imag, bdat->real);
|
||||
n = f_mul(bdat->real, f_add(ONE, f_mul(r, r)));
|
||||
if (flo)
|
||||
return f_complex_new2(CLASS_OF(self),
|
||||
(*func)(self, n),
|
||||
(*func)(f_negate(f_mul(self, r)), n));
|
||||
return f_complex_new2(CLASS_OF(self),
|
||||
(*func)(f_add(adat->real,
|
||||
f_mul(adat->imag, r)), n),
|
||||
(*func)(f_sub(adat->imag,
|
||||
f_mul(adat->real, r)), n));
|
||||
}
|
||||
else {
|
||||
VALUE r, n;
|
||||
|
||||
r = (*func)(bdat->real, bdat->imag);
|
||||
n = f_mul(bdat->imag, f_add(ONE, f_mul(r, r)));
|
||||
if (flo)
|
||||
return f_complex_new2(CLASS_OF(self),
|
||||
(*func)(f_mul(self, r), n),
|
||||
(*func)(f_negate(self), n));
|
||||
return f_complex_new2(CLASS_OF(self),
|
||||
(*func)(f_add(f_mul(adat->real, r),
|
||||
adat->imag), n),
|
||||
(*func)(f_sub(f_mul(adat->imag, r),
|
||||
adat->real), n));
|
||||
}
|
||||
return (*func)(f_mul(self, f_conj(other)), f_abs2(other));
|
||||
}
|
||||
if (k_numeric_p(other) && f_real_p(other)) {
|
||||
get_dat1(self);
|
||||
|
@ -858,6 +872,19 @@ static VALUE
|
|||
nucomp_abs(VALUE self)
|
||||
{
|
||||
get_dat1(self);
|
||||
|
||||
if (f_zero_p(dat->real)) {
|
||||
VALUE a = f_abs(dat->imag);
|
||||
if (k_float_p(dat->real) && !k_float_p(dat->imag))
|
||||
a = f_to_f(a);
|
||||
return a;
|
||||
}
|
||||
if (f_zero_p(dat->imag)) {
|
||||
VALUE a = f_abs(dat->real);
|
||||
if (!k_float_p(dat->real) && k_float_p(dat->imag))
|
||||
a = f_to_f(a);
|
||||
return a;
|
||||
}
|
||||
return m_hypot(dat->real, dat->imag);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue