/* * call-seq: * str.to_c -> complex * * Returns a complex which denotes the string form. The parser * ignores leading whitespaces and trailing garbage. Any digit * sequences can be separated by an underscore. Returns zero for null * or garbage string. * * For example: * * '9'.to_c #=> (9+0i) * '2.5'.to_c #=> (2.5+0i) * '2.5/1'.to_c #=> ((5/2)+0i) * '-3/2'.to_c #=> ((-3/2)+0i) * '-i'.to_c #=> (0-1i) * '45i'.to_c #=> (0+45i) * '3-4i'.to_c #=> (3-4i) * '-4e2-4e-2i'.to_c #=> (-400.0-0.04i) * '-0.0-0.0i'.to_c #=> (-0.0-0.0i) * '1/2+3/4i'.to_c #=> ((1/2)+(3/4)*i) * 'ruby'.to_c #=> (0+0i) */ static VALUE string_to_c(VALUE self) { VALUE s, a, backref; backref = rb_backref_get(); rb_match_busy(backref); s = f_gsub(self, underscores_pat, an_underscore); a = string_to_c_internal(s); rb_backref_set(backref); if (!NIL_P(RARRAY_PTR(a)[0])) return RARRAY_PTR(a)[0]; return rb_complex_new1(INT2FIX(0)); }
static VALUE nucomp_s_convert(int argc, VALUE *argv, VALUE klass) { 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 Complex"); backref = rb_backref_get(); rb_match_busy(backref); if (RB_TYPE_P(a1, T_STRING)) { a1 = string_to_c_strict(a1); } if (RB_TYPE_P(a2, T_STRING)) { a2 = string_to_c_strict(a2); } rb_backref_set(backref); if (RB_TYPE_P(a1, T_COMPLEX)) { { get_dat1(a1); if (k_exact_zero_p(dat->imag)) a1 = dat->real; } } if (RB_TYPE_P(a2, T_COMPLEX)) { { get_dat1(a2); if (k_exact_zero_p(dat->imag)) a2 = dat->real; } } if (RB_TYPE_P(a1, T_COMPLEX)) { if (argc == 1 || (k_exact_zero_p(a2))) return a1; } if (argc == 1) { if (k_numeric_p(a1) && !f_real_p(a1)) return a1; /* should raise exception for consistency */ if (!k_numeric_p(a1)) return rb_convert_type(a1, T_COMPLEX, "Complex", "to_c"); } else { if ((k_numeric_p(a1) && k_numeric_p(a2)) && (!f_real_p(a1) || !f_real_p(a2))) return f_add(a1, f_mul(a2, f_complex_new_bang2(rb_cComplex, ZERO, ONE))); } { VALUE argv2[2]; argv2[0] = a1; argv2[1] = a2; return nucomp_s_new(argc, argv2, klass); } }
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); } }
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 nucomp_s_convert(int argc, VALUE *argv, VALUE klass) { VALUE a1, a2, backref; rb_scan_args(argc, argv, "11", &a1, &a2); backref = rb_backref_get(); rb_match_busy(backref); switch (TYPE(a1)) { case T_FIXNUM: case T_BIGNUM: case T_FLOAT: break; case T_STRING: a1 = string_to_c_strict(a1); break; } switch (TYPE(a2)) { case T_FIXNUM: case T_BIGNUM: case T_FLOAT: break; case T_STRING: a2 = string_to_c_strict(a2); break; } rb_backref_set(backref); switch (TYPE(a1)) { case T_COMPLEX: { get_dat1(a1); if (k_exact_p(dat->imag) && f_zero_p(dat->imag)) a1 = dat->real; } } switch (TYPE(a2)) { case T_COMPLEX: { get_dat1(a2); if (k_exact_p(dat->imag) && f_zero_p(dat->imag)) a2 = dat->real; } } switch (TYPE(a1)) { case T_COMPLEX: if (argc == 1 || (k_exact_p(a2) && f_zero_p(a2))) return a1; } if (argc == 1) { if (k_numeric_p(a1) && !f_real_p(a1)) return a1; } else { if ((k_numeric_p(a1) && k_numeric_p(a2)) && (!f_real_p(a1) || !f_real_p(a2))) return f_add(a1, f_mul(a2, f_complex_new_bang2(rb_cComplex, ZERO, ONE))); } { VALUE argv2[2]; argv2[0] = a1; argv2[1] = a2; return nucomp_s_new(argc, argv2, klass); } }