Example #1
0
static VALUE
string_to_r(VALUE self)
{
    VALUE s = f_gsub(self, underscores_pat, an_underscore);
    VALUE a = string_to_r_internal(s);
    if (!NIL_P(RARRAY_AT(a, 0)))
	return RARRAY_AT(a, 0);
    return rb_rational_new1(INT2FIX(0));
}
Example #2
0
/*
 * call-seq:
 *    str.to_r  ->  rational
 *
 * Returns a rational which denotes the string form.  The parser
 * ignores leading whitespaces and trailing garbage.  Any digit
 * sequences can be separeted by an underscore.  Returns zero for null
 * or garbage string.
 *
 * NOTE: '0.3'.to_r isn't the same as 0.3.to_r.  The former is
 * equivalent to '3/10'.to_r, but the latter isn't so.
 *
 * For example:
 *
 *    '  2  '.to_r       #=> (2/1)
 *    '300/2'.to_r       #=> (150/1)
 *    '-9.2'.to_r        #=> (-46/5)
 *    '-9.2e2'.to_r      #=> (-920/1)
 *    '1_234_567'.to_r   #=> (1234567/1)
 *    '21 june 09'.to_r  #=> (21/1)
 *    '21/06/09'.to_r    #=> (7/2)
 *    'bwv 1079'.to_r    #=> (0/1)
 */
static VALUE
string_to_r(VALUE self, SEL sel)
{
    VALUE s, a, backref;

    backref = rb_backref_get();
    rb_match_busy(backref);

    s = f_gsub(self, underscores_pat, an_underscore);
    a = string_to_r_internal(s);

    rb_backref_set(backref);

    if (!NIL_P(RARRAY_PTR(a)[0]))
	return RARRAY_PTR(a)[0];
    return rb_rational_new1(INT2FIX(0));
}
Example #3
0
static VALUE
string_to_r_internal(VALUE self)
{
    VALUE s, m;

    s = self;

    if (RSTRING_LEN(s) == 0)
	return rb_assoc_new(Qnil, self);

    m = f_match(rat_pat, s);

    if (!NIL_P(m)) {
	VALUE v, ifp, exp, ip, fp;
	VALUE si = f_aref(m, INT2FIX(1));
	VALUE nu = f_aref(m, INT2FIX(2));
	VALUE de = f_aref(m, INT2FIX(3));
	VALUE re = f_post_match(m);

	{
	    VALUE a;

	    a = f_split(nu, an_e_pat);
	    ifp = RARRAY_PTR(a)[0];
	    if (RARRAY_LEN(a) != 2)
		exp = Qnil;
	    else
		exp = RARRAY_PTR(a)[1];

	    a = f_split(ifp, a_dot_pat);
	    ip = RARRAY_PTR(a)[0];
	    if (RARRAY_LEN(a) != 2)
		fp = Qnil;
	    else
		fp = RARRAY_PTR(a)[1];
	}

	v = rb_rational_new1(f_to_i(ip));

	if (!NIL_P(fp)) {
	    char *p = StringValuePtr(fp);
	    long count = 0;
	    VALUE l;

	    while (*p) {
		if (rb_isdigit(*p))
		    count++;
		p++;
	    }

	    l = f_expt(INT2FIX(10), LONG2NUM(count));
	    v = f_mul(v, l);
	    v = f_add(v, f_to_i(fp));
	    v = f_div(v, l);
	}
	if (!NIL_P(si) && *StringValuePtr(si) == '-')
	    v = f_negate(v);
	if (!NIL_P(exp))
	    v = f_mul(v, f_expt(INT2FIX(10), f_to_i(exp)));
#if 0
	if (!NIL_P(de) && (!NIL_P(fp) || !NIL_P(exp)))
	    return rb_assoc_new(v, rb_usascii_str_new2("dummy"));
#endif
	if (!NIL_P(de))
	    v = f_div(v, f_to_i(de));

	return rb_assoc_new(v, re);
    }
    return rb_assoc_new(Qnil, self);
}
Example #4
0
/*
 * call-seq:
 *    int.to_r  ->  rational
 *
 * Returns the value as a rational.
 *
 * For example:
 *
 *    1.to_r        #=> (1/1)
 *    (1<<64).to_r  #=> (18446744073709551616/1)
 */
static VALUE
integer_to_r(VALUE self, SEL sel)
{
    return rb_rational_new1(self);
}
Example #5
0
/*
 * call-seq:
 *    nil.to_r  ->  (0/1)
 *
 * Returns zero as a rational.
 */
static VALUE
nilclass_to_r(VALUE self, SEL sel)
{
    return rb_rational_new1(INT2FIX(0));
}