diff options
Diffstat (limited to 'math.c')
-rw-r--r-- | math.c | 20 |
1 files changed, 19 insertions, 1 deletions
@@ -591,13 +591,31 @@ math_sqrt(VALUE obj, VALUE x) return rb_math_sqrt(x); } +#define f_boolcast(x) ((x) ? Qtrue : Qfalse) +inline static VALUE +f_negative_p(VALUE x) +{ + if (FIXNUM_P(x)) + return f_boolcast(FIX2LONG(x) < 0); + return rb_funcall(x, '<', 1, INT2FIX(0)); +} +inline static VALUE +f_signbit(VALUE x) +{ + if (RB_TYPE_P(x, T_FLOAT)) { + double f = RFLOAT_VALUE(x); + return f_boolcast(!isnan(f) && signbit(f)); + } + return f_negative_p(x); +} + VALUE rb_math_sqrt(VALUE x) { double d; if (RB_TYPE_P(x, T_COMPLEX)) { - int neg = signbit(RCOMPLEX(x)->imag); + int neg = f_signbit(RCOMPLEX(x)->imag); double re = Get_Double(RCOMPLEX(x)->real), im; d = Get_Double(rb_complex_abs(x)); im = sqrt((d - re) / 2.0); |