summaryrefslogtreecommitdiff
path: root/rational.c
diff options
context:
space:
mode:
Diffstat (limited to 'rational.c')
-rw-r--r--rational.c65
1 files changed, 46 insertions, 19 deletions
diff --git a/rational.c b/rational.c
index 00b09409af..00b4fa74c3 100644
--- a/rational.c
+++ b/rational.c
@@ -1,5 +1,5 @@
/*
- rational.c: Coded by Tadayoshi Funaba 2008-2010
+ rational.c: Coded by Tadayoshi Funaba 2008-2011
This implementation is based on Keiju Ishitsuka's Rational library
which is written in ruby.
@@ -136,8 +136,22 @@ fun1(floor)
fun1(inspect)
fun1(integer_p)
fun1(negate)
-fun1(to_f)
-fun1(to_i)
+
+inline static VALUE
+f_to_i(VALUE x)
+{
+ if (TYPE(x) == T_STRING)
+ return rb_str_to_inum(x, 10, 0);
+ return rb_funcall(x, id_to_i, 0);
+}
+inline static VALUE
+f_to_f(VALUE x)
+{
+ if (TYPE(x) == T_STRING)
+ return DBL2NUM(rb_str_to_dbl(x, 0));
+ return rb_funcall(x, id_to_f, 0);
+}
+
fun1(to_s)
fun1(truncate)
@@ -153,6 +167,8 @@ fun2(expt)
fun2(fdiv)
fun2(idiv)
+#define f_expt10(x) f_expt(INT2FIX(10), x)
+
inline static VALUE
f_negative_p(VALUE x)
{
@@ -1208,7 +1224,7 @@ f_round_common(int argc, VALUE *argv, VALUE self, VALUE (*func)(VALUE))
if (!k_integer_p(n))
rb_raise(rb_eTypeError, "not an integer");
- b = f_expt(INT2FIX(10), n);
+ b = f_expt10(n);
s = f_mul(self, b);
s = (*func)(s);
@@ -2035,25 +2051,37 @@ string_to_r_internal(VALUE self)
{
VALUE a;
- a = f_split(nu, an_e_pat);
- ifp = RARRAY_PTR(a)[0];
- if (RARRAY_LEN(a) != 2)
+ if (!strpbrk(RSTRING_PTR(nu), "eE")) {
+ ifp = nu; /* not a copy */
exp = Qnil;
- else
- exp = RARRAY_PTR(a)[1];
+ }
+ else {
+ 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)
+ if (!strchr(RSTRING_PTR(ifp), '.')) {
+ ip = ifp; /* not a copy */
fp = Qnil;
- else
- fp = RARRAY_PTR(a)[1];
+ }
+ else {
+ 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);
+ char *p = RSTRING_PTR(fp);
long count = 0;
VALUE l;
@@ -2062,16 +2090,15 @@ string_to_r_internal(VALUE self)
count++;
p++;
}
-
- l = f_expt(INT2FIX(10), LONG2NUM(count));
+ l = f_expt10(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) == '-')
+ if (!NIL_P(si) && *RSTRING_PTR(si) == '-')
v = f_negate(v);
if (!NIL_P(exp))
- v = f_mul(v, f_expt(INT2FIX(10), f_to_i(exp)));
+ v = f_mul(v, f_expt10(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"));