summaryrefslogtreecommitdiff
path: root/rational.c
diff options
context:
space:
mode:
authortadf <tadf@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-07-19 13:25:05 (GMT)
committertadf <tadf@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-07-19 13:25:05 (GMT)
commitbb45f1b2b8a21a8e6de705c9a68724a49563c66c (patch)
treee655a5c9cc39270503a5b9c2db345bb5e8d4214f /rational.c
parenta7290749a5a6d4e0420d4b18a8153b25f86c34f2 (diff)
* rational.c (float_to_r): an improvement.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@24206 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'rational.c')
-rw-r--r--rational.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/rational.c b/rational.c
index c14bc94..e5ae730 100644
--- a/rational.c
+++ b/rational.c
@@ -1695,6 +1695,9 @@ float_decode(VALUE self)
}
#endif
+#define id_lshift rb_intern("<<")
+#define f_lshift(x,n) rb_funcall(x, id_lshift, 1, n)
+
/*
* call-seq:
* flt.to_r -> rational
@@ -1717,7 +1720,20 @@ float_to_r(VALUE self)
VALUE f, n;
float_decode_internal(self, &f, &n);
+#if FLT_RADIX == 2
+ {
+ long ln = FIX2LONG(n);
+
+ if (ln == 0)
+ return f_to_r(f);
+ if (ln > 0)
+ return f_to_r(f_lshift(f, n));
+ ln = -ln;
+ return rb_rational_new2(f, f_lshift(ONE, INT2FIX(ln)));
+ }
+#else
return f_to_r(f_mul(f, f_expt(INT2FIX(FLT_RADIX), n)));
+#endif
}
static VALUE rat_pat, an_e_pat, a_dot_pat, underscores_pat, an_underscore;