diff --git a/complex.c b/complex.c index 5b5f17edfa..1a851dd3b5 100644 --- a/complex.c +++ b/complex.c @@ -182,8 +182,12 @@ fun2(quo) inline static int f_negative_p(VALUE x) { - if (FIXNUM_P(x)) - return FIXNUM_NEGATIVE_P(x); + if (RB_INTEGER_TYPE_P(x)) + return INT_NEGATIVE_P(x); + else if (RB_FLOAT_TYPE_P(x)) + return RFLOAT_VALUE(x) < 0.0; + else if (RB_TYPE_P(x, T_RATIONAL)) + return INT_NEGATIVE_P(RRATIONAL(x)->num); return rb_num_negative_p(x); } @@ -2045,8 +2049,8 @@ static VALUE numeric_arg(VALUE self) { if (f_positive_p(self)) - return INT2FIX(0); - return rb_const_get(rb_mMath, id_PI); + return INT2FIX(0); + return DBL2NUM(M_PI); } /* @@ -2062,6 +2066,8 @@ numeric_rect(VALUE self) return rb_assoc_new(self, INT2FIX(0)); } +static VALUE float_arg(VALUE self); + /* * call-seq: * num.polar -> array @@ -2071,7 +2077,25 @@ numeric_rect(VALUE self) static VALUE numeric_polar(VALUE self) { - return rb_assoc_new(f_abs(self), f_arg(self)); + VALUE abs, arg; + + if (RB_INTEGER_TYPE_P(self)) { + abs = rb_int_abs(self); + arg = numeric_arg(self); + } + else if (RB_FLOAT_TYPE_P(self)) { + abs = rb_float_abs(self); + arg = float_arg(self); + } + else if (RB_TYPE_P(self, T_RATIONAL)) { + abs = rb_rational_abs(self); + arg = numeric_arg(self); + } + else { + abs = f_abs(self); + arg = f_arg(self); + } + return rb_assoc_new(abs, arg); } /* diff --git a/internal.h b/internal.h index acab0d31b7..a3ce94988f 100644 --- a/internal.h +++ b/internal.h @@ -1141,6 +1141,8 @@ void Init_newline(void); #define FIXNUM_NEGATIVE_P(num) ((SIGNED_VALUE)(num) < 0) #define FIXNUM_ZERO_P(num) ((num) == INT2FIX(0)) +#define INT_NEGATIVE_P(x) (FIXNUM_P(x) ? FIXNUM_NEGATIVE_P(x) : BIGNUM_NEGATIVE_P(x)) + #ifndef ROUND_DEFAULT # define ROUND_DEFAULT RUBY_NUM_ROUND_HALF_EVEN #endif @@ -1181,6 +1183,7 @@ VALUE rb_int_and(VALUE x, VALUE y); VALUE rb_int_lshift(VALUE x, VALUE y); VALUE rb_int_div(VALUE x, VALUE y); VALUE rb_int_abs(VALUE num); +VALUE rb_float_abs(VALUE flt); #if USE_FLONUM #define RUBY_BIT_ROTL(v, n) (((v) << (n)) | ((v) >> ((sizeof(v) * 8) - n))) @@ -1373,6 +1376,7 @@ VALUE rb_rational_plus(VALUE self, VALUE other); VALUE rb_lcm(VALUE x, VALUE y); VALUE rb_rational_reciprocal(VALUE x); VALUE rb_cstr_to_rat(const char *, int); +VALUE rb_rational_abs(VALUE self); /* re.c */ VALUE rb_reg_compile(VALUE str, int options, const char *sourcefile, int sourceline); diff --git a/numeric.c b/numeric.c index 959626e28d..e7cb105b7d 100644 --- a/numeric.c +++ b/numeric.c @@ -1678,8 +1678,8 @@ flo_to_f(VALUE num) * */ -static VALUE -flo_abs(VALUE flt) +VALUE +rb_float_abs(VALUE flt) { double val = fabs(RFLOAT_VALUE(flt)); return DBL2NUM(val); @@ -5406,8 +5406,8 @@ Init_Numeric(void) rb_define_method(rb_cFloat, "eql?", flo_eql, 1); rb_define_method(rb_cFloat, "hash", flo_hash, 0); rb_define_method(rb_cFloat, "to_f", flo_to_f, 0); - rb_define_method(rb_cFloat, "abs", flo_abs, 0); - rb_define_method(rb_cFloat, "magnitude", flo_abs, 0); + rb_define_method(rb_cFloat, "abs", rb_float_abs, 0); + rb_define_method(rb_cFloat, "magnitude", rb_float_abs, 0); rb_define_method(rb_cFloat, "zero?", flo_zero_p, 0); rb_define_method(rb_cFloat, "to_i", flo_to_i, 0); diff --git a/rational.c b/rational.c index d9ff5ce344..0a120368c3 100644 --- a/rational.c +++ b/rational.c @@ -28,7 +28,6 @@ #define GMP_GCD_DIGITS 1 #define INT_POSITIVE_P(x) (FIXNUM_P(x) ? FIXNUM_POSITIVE_P(x) : BIGNUM_POSITIVE_P(x)) -#define INT_NEGATIVE_P(x) (FIXNUM_P(x) ? FIXNUM_NEGATIVE_P(x) : BIGNUM_NEGATIVE_P(x)) #define INT_ZERO_P(x) (FIXNUM_P(x) ? FIXNUM_ZERO_P(x) : rb_bigzero_p(x)) VALUE rb_cRational;