summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--math.c15
2 files changed, 18 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index d97fb65..5696431 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Tue Mar 3 14:47:30 2015 Kazuki Tanaka <gogotanaka@ruby-lang.org>
+
+ * math.c (num2dbl_with_to_f): direct casting from Rational to double.
+ [Feature #10909]
+
Tue Mar 3 07:52:20 2015 Rei Odaira <Rei.Odaira@gmail.com>
* test/ruby/test_symbol.rb: avoid a false positive in AIX.
diff --git a/math.c b/math.c
index 5d4c2bb..fc03b5b 100644
--- a/math.c
+++ b/math.c
@@ -32,13 +32,20 @@ basic_to_f_p(VALUE klass)
return rb_method_basic_definition_p(klass, id_to_f);
}
+#define fix2dbl_without_to_f(x) (double)FIX2LONG(x)
+#define big2dbl_without_to_f(x) rb_big2dbl(x)
+#define int2dbl_without_to_f(x) (FIXNUM_P(x) ? fix2dbl_without_to_f(x) : big2dbl_without_to_f(x))
+#define rat2dbl_without_to_f(x) \
+ (int2dbl_without_to_f(rb_rational_num(x)) / \
+ int2dbl_without_to_f(rb_rational_den(x)))
+
static inline double
num2dbl_with_to_f(VALUE num)
{
if (SPECIAL_CONST_P(num)) {
if (FIXNUM_P(num)) {
if (basic_to_f_p(rb_cFixnum))
- return (double)FIX2LONG(num);
+ return fix2dbl_without_to_f(num);
}
else if (FLONUM_P(num)) {
return RFLOAT_VALUE(num);
@@ -50,7 +57,11 @@ num2dbl_with_to_f(VALUE num)
return RFLOAT_VALUE(num);
case T_BIGNUM:
if (basic_to_f_p(rb_cBignum))
- return rb_big2dbl(num);
+ return big2dbl_without_to_f(num);
+ break;
+ case T_RATIONAL:
+ if (basic_to_f_p(rb_cRational))
+ return rat2dbl_without_to_f(num);
break;
}
}