summaryrefslogtreecommitdiff
path: root/math.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-01-30 08:28:32 (GMT)
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-01-30 08:28:32 (GMT)
commitdf445b470e9b9169c793019c51b834e186526b15 (patch)
treefbc946df6ee980d646e1c3a0fc7fb318146800eb /math.c
parent3d775f1c6fe9f558be8c9d4a3f3db8f472fd2bae (diff)
math.c: optimization for Bignum
* math.c (num2dbl_with_to_f): make faster when Bignum passed by direct conversion using rb_big2dbl(). [Feature #10800] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49449 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'math.c')
-rw-r--r--math.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/math.c b/math.c
index 3f0b11e..5d4c2bb 100644
--- a/math.c
+++ b/math.c
@@ -26,13 +26,38 @@ static ID id_to_f;
VALUE rb_mMath;
VALUE rb_eMathDomainError;
-#define fix_to_f_optimizable() rb_method_basic_definition_p(rb_cFixnum, id_to_f)
-#define Get_Float(x) \
- ((RB_TYPE_P((x), T_FLOAT) ? (void)0 : ((x) = rb_to_float(x))), RFLOAT_VALUE(x))
-#define Get_Double(x) \
- (FIXNUM_P(x) && fix_to_f_optimizable() ? \
- (double)FIX2LONG(x) : \
- Get_Float(x))
+static inline int
+basic_to_f_p(VALUE klass)
+{
+ return rb_method_basic_definition_p(klass, id_to_f);
+}
+
+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);
+ }
+ else if (FLONUM_P(num)) {
+ return RFLOAT_VALUE(num);
+ }
+ }
+ else {
+ switch (BUILTIN_TYPE(num)) {
+ case T_FLOAT:
+ return RFLOAT_VALUE(num);
+ case T_BIGNUM:
+ if (basic_to_f_p(rb_cBignum))
+ return rb_big2dbl(num);
+ break;
+ }
+ }
+ return RFLOAT_VALUE(rb_to_float(num));
+}
+
+#define Get_Double(x) num2dbl_with_to_f(x)
#define domain_error(msg) \
rb_raise(rb_eMathDomainError, "Numerical argument is out of domain - " #msg)