VALUE rb_math_sqrt(VALUE x) { double d; if (RB_TYPE_P(x, T_COMPLEX)) { VALUE 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); re = sqrt((d + re) / 2.0); if (neg) im = -im; return rb_complex_new(DBL2NUM(re), DBL2NUM(im)); } d = Get_Double(x); /* check for domain error */ if (d < 0.0) domain_error("sqrt"); if (d == 0.0) return DBL2NUM(0.0); return DBL2NUM(sqrt(d)); }
/* :nodoc: */ static VALUE nurat_coerce(VALUE self, SEL sel, VALUE other) { switch (TYPE(other)) { case T_FIXNUM: case T_BIGNUM: return rb_assoc_new(f_rational_new_bang1(CLASS_OF(self), other), self); case T_FLOAT: return rb_assoc_new(other, f_to_f(self)); case T_RATIONAL: return rb_assoc_new(other, self); case T_COMPLEX: if (k_exact_zero_p(RCOMPLEX(other)->imag)) return rb_assoc_new(f_rational_new_bang1 (CLASS_OF(self), RCOMPLEX(other)->real), self); } rb_raise(rb_eTypeError, "%s can't be coerced into %s", rb_obj_classname(other), rb_obj_classname(self)); return Qnil; }
static VALUE nurat_s_convert(VALUE klass, SEL sel, int argc, VALUE *argv) { VALUE a1, a2, backref; rb_scan_args(argc, argv, "11", &a1, &a2); if (NIL_P(a1) || (argc == 2 && NIL_P(a2))) rb_raise(rb_eTypeError, "can't convert nil into Rational"); switch (TYPE(a1)) { case T_COMPLEX: if (k_exact_zero_p(RCOMPLEX(a1)->imag)) a1 = RCOMPLEX(a1)->real; } switch (TYPE(a2)) { case T_COMPLEX: if (k_exact_zero_p(RCOMPLEX(a2)->imag)) a2 = RCOMPLEX(a2)->real; } backref = rb_backref_get(); rb_match_busy(backref); switch (TYPE(a1)) { case T_FIXNUM: case T_BIGNUM: break; case T_FLOAT: a1 = f_to_r(a1); break; case T_STRING: a1 = string_to_r_strict(a1); break; } switch (TYPE(a2)) { case T_FIXNUM: case T_BIGNUM: break; case T_FLOAT: a2 = f_to_r(a2); break; case T_STRING: a2 = string_to_r_strict(a2); break; } rb_backref_set(backref); switch (TYPE(a1)) { case T_RATIONAL: if (argc == 1 || (k_exact_one_p(a2))) return a1; } if (argc == 1) { if (!(k_numeric_p(a1) && k_integer_p(a1))) return rb_convert_type(a1, T_RATIONAL, "Rational", "to_r"); } else { if ((k_numeric_p(a1) && k_numeric_p(a2)) && (!f_integer_p(a1) || !f_integer_p(a2))) return f_div(a1, a2); } { VALUE argv2[2]; argv2[0] = a1; argv2[1] = a2; return nurat_s_new(argc, argv2, klass); } }
static VALUE nurat_s_convert(int argc, VALUE *argv, VALUE klass) { VALUE a1, a2; if (rb_scan_args(argc, argv, "02", &a1, &a2) == 1) { a2 = ONE; } switch (TYPE(a1)) { case T_COMPLEX: if (k_float_p(RCOMPLEX(a1)->image) || !f_zero_p(RCOMPLEX(a1)->image)) { VALUE s = f_to_s(a1); rb_raise(rb_eRangeError, "can't accept %s", StringValuePtr(s)); } a1 = RCOMPLEX(a1)->real; } switch (TYPE(a2)) { case T_COMPLEX: if (k_float_p(RCOMPLEX(a2)->image) || !f_zero_p(RCOMPLEX(a2)->image)) { VALUE s = f_to_s(a2); rb_raise(rb_eRangeError, "can't accept %s", StringValuePtr(s)); } a2 = RCOMPLEX(a2)->real; } switch (TYPE(a1)) { case T_FIXNUM: case T_BIGNUM: break; case T_FLOAT: a1 = f_to_r(a1); break; case T_STRING: a1 = string_to_r_strict(a1); break; } switch (TYPE(a2)) { case T_FIXNUM: case T_BIGNUM: break; case T_FLOAT: a2 = f_to_r(a2); break; case T_STRING: a2 = string_to_r_strict(a2); break; } switch (TYPE(a1)) { case T_RATIONAL: if (NIL_P(a2) || f_zero_p(a2)) return a1; else return f_div(a1, a2); } switch (TYPE(a2)) { case T_RATIONAL: return f_div(a1, a2); } return nurat_s_new(klass, a1, a2); }
static VALUE nurat_s_convert(int argc, VALUE *argv, VALUE klass) { VALUE a1, a2, backref; rb_scan_args(argc, argv, "11", &a1, &a2); switch (TYPE(a1)) { case T_COMPLEX: if (k_exact_p(RCOMPLEX(a1)->imag) && f_zero_p(RCOMPLEX(a1)->imag)) a1 = RCOMPLEX(a1)->real; } switch (TYPE(a2)) { case T_COMPLEX: if (k_exact_p(RCOMPLEX(a2)->imag) && f_zero_p(RCOMPLEX(a2)->imag)) a2 = RCOMPLEX(a2)->real; } backref = rb_backref_get(); rb_match_busy(backref); switch (TYPE(a1)) { case T_FIXNUM: case T_BIGNUM: break; case T_FLOAT: a1 = f_to_r(a1); break; case T_STRING: a1 = string_to_r_strict(a1); break; } switch (TYPE(a2)) { case T_FIXNUM: case T_BIGNUM: break; case T_FLOAT: a2 = f_to_r(a2); break; case T_STRING: a2 = string_to_r_strict(a2); break; } rb_backref_set(backref); switch (TYPE(a1)) { case T_RATIONAL: if (argc == 1 || (k_exact_p(a2) && f_one_p(a2))) return a1; } if (argc == 1) { if (k_numeric_p(a1) && !f_integer_p(a1)) return a1; } else { if ((k_numeric_p(a1) && k_numeric_p(a2)) && (!f_integer_p(a1) || !f_integer_p(a2))) return f_div(a1, a2); } { VALUE argv2[2]; argv2[0] = a1; argv2[1] = a2; return nurat_s_new(argc, argv2, klass); } }