aboutsummaryrefslogtreecommitdiffstats
path: root/complex.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-02-24 13:58:52 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-02-24 13:58:52 +0000
commit3bcb10ad2a11f60ec8458ad24f64b0ec97a816cc (patch)
treee1dbae865f6e785771dd2bb93bf34cd5eebedfb7 /complex.c
parent87e3aec84d13f179fe56a24243baf0f9b55ac87c (diff)
downloadruby-3bcb10ad2a11f60ec8458ad24f64b0ec97a816cc.tar.gz
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.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/complex.c b/complex.c
index 251c120029..a169c95b71 100644
--- a/complex.c
+++ b/complex.c
@@ -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)) {