summaryrefslogtreecommitdiff
path: root/numeric.c
diff options
context:
space:
mode:
authorshyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-03-06 11:14:05 (GMT)
committershyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-03-06 11:14:05 (GMT)
commit74cdd893eb102ba98e735f2a24c710e1928261a9 (patch)
tree148c82adfc714aaa2a3d60cda2c18c4f78ed9f76 /numeric.c
parentcf2a68662aadcbed4a92cfdad4d992f894f3767f (diff)
optimize FIXABLE macro
Looking at the source code, FIXABLE tends to be just before LOING2FIX to check applicability of that operation. Why not try computing first then check for overflow, which should be optimial. I also tried the same thing for unsigned types but resulted in slower execution. It seems RB_POSFIXABLE() is fast enough on modern CPUs. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57789 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'numeric.c')
-rw-r--r--numeric.c33
1 files changed, 12 insertions, 21 deletions
diff --git a/numeric.c b/numeric.c
index 3d2b501..4f789e4 100644
--- a/numeric.c
+++ b/numeric.c
@@ -1279,10 +1279,7 @@ flo_mod(VALUE x, VALUE y)
static VALUE
dbl2ival(double d)
{
- if (FIXABLE(d)) {
- return LONG2FIX((long)d);
- }
- return rb_dbl2big(d);
+ return rb_dbl2ival(d);
}
/*
@@ -1967,7 +1964,6 @@ static VALUE
flo_floor(int argc, VALUE *argv, VALUE num)
{
double number, f;
- long val;
int ndigits = 0;
if (rb_check_arity(argc, 0, 1)) {
@@ -1984,11 +1980,7 @@ flo_floor(int argc, VALUE *argv, VALUE num)
return DBL2NUM(f);
}
f = floor(number);
- if (!FIXABLE(f)) {
- return rb_dbl2big(f);
- }
- val = (long)f;
- return LONG2FIX(val);
+ return dbl2ival(f);
}
/*
@@ -2327,16 +2319,11 @@ static VALUE
flo_to_i(VALUE num)
{
double f = RFLOAT_VALUE(num);
- long val;
if (f > 0.0) f = floor(f);
if (f < 0.0) f = ceil(f);
- if (!FIXABLE(f)) {
- return rb_dbl2big(f);
- }
- val = (long)f;
- return LONG2FIX(val);
+ return dbl2ival(f);
}
/*
@@ -3020,13 +3007,17 @@ VALUE
rb_num2fix(VALUE val)
{
long v;
+ VALUE w;
- if (FIXNUM_P(val)) return val;
-
- v = rb_num2long(val);
- if (!FIXABLE(v))
+ if (FIXNUM_P(val)) {
+ return val;
+ }
+ else if (rb_long2fix_overflow((v = rb_num2long(val)), &w)) {
rb_raise(rb_eRangeError, "integer %ld out of range of fixnum", v);
- return LONG2FIX(v);
+ }
+ else {
+ return w;
+ }
}
#if HAVE_LONG_LONG