aboutsummaryrefslogtreecommitdiffstats
path: root/math.c
diff options
context:
space:
mode:
Diffstat (limited to 'math.c')
-rw-r--r--math.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/math.c b/math.c
index 8d36389a28..9cdf9e5565 100644
--- a/math.c
+++ b/math.c
@@ -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);