diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-02-24 13:58:52 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-02-24 13:58:52 +0000 |
commit | 3bcb10ad2a11f60ec8458ad24f64b0ec97a816cc (patch) | |
tree | e1dbae865f6e785771dd2bb93bf34cd5eebedfb7 /complex.c | |
parent | 87e3aec84d13f179fe56a24243baf0f9b55ac87c (diff) |
complex.c: multiply as rotation
* complex.c (nucomp_mul): calculate as rotation in complex plane
if matrix calculation resulted in NaN.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49723 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'complex.c')
-rw-r--r-- | complex.c | 35 |
1 files changed, 35 insertions, 0 deletions
@@ -17,6 +17,9 @@ VALUE rb_cComplex; +static VALUE nucomp_abs(VALUE self); +static VALUE nucomp_arg(VALUE self); + static ID id_abs, id_arg, id_convert, id_denominator, id_eqeq_p, id_expt, id_fdiv, id_negate, id_numerator, id_quo, @@ -720,6 +723,38 @@ nucomp_mul(VALUE self, VALUE other) imag = f_add(f_mul(adat->real, bdat->imag), f_mul(adat->imag, bdat->real)); + if ((RB_FLOAT_TYPE_P(real) && isnan(RFLOAT_VALUE(real))) || + (RB_FLOAT_TYPE_P(imag) && isnan(RFLOAT_VALUE(imag)))) { + VALUE abs = f_mul(nucomp_abs(self), nucomp_abs(other)); + VALUE arg = f_add(nucomp_arg(self), nucomp_arg(other)); + if (f_zero_p(arg)) { + real = abs; + imag = INT2FIX(0); + } + else if (RB_FLOAT_TYPE_P(arg)) { + double a = RFLOAT_VALUE(arg); + if (a == M_PI) { + real = f_negate(abs); + imag = INT2FIX(0); + } + else if (a == M_PI/2) { + imag = abs; + real = INT2FIX(0); + } + else if (a == M_PI*3/2) { + imag = f_negate(abs); + real = INT2FIX(0); + } + else { + goto polar; + } + } + else { + polar: + return f_complex_polar(CLASS_OF(self), abs, arg); + } + } + return f_complex_new2(CLASS_OF(self), real, imag); } if (k_numeric_p(other) && f_real_p(other)) { |