* time.c (MUL_OVERFLOW_FIXWV_P): defined for FIXWV.
* time.c (wmul): use MUL_OVERFLOW_FIXWV_P and only switch. * time.c (wmul): use mul which has Fixnum optimization. * time.c (rb_time_magnify): If WIDEVALUE_IS_WIDER, wmul() has the same optimized logic, else mul() has also the similar logic for Fixnum. * time.c (rb_time_unmagnify): almost ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54221 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
74d7b281d3
commit
03d0501f51
13
ChangeLog
13
ChangeLog
@ -1,3 +1,16 @@
|
||||
Tue Mar 22 03:45:03 2016 NARUSE, Yui <naruse@ruby-lang.org>
|
||||
|
||||
* time.c (MUL_OVERFLOW_FIXWV_P): defined for FIXWV.
|
||||
|
||||
* time.c (wmul): use MUL_OVERFLOW_FIXWV_P and only switch.
|
||||
|
||||
* time.c (wmul): use mul which has Fixnum optimization.
|
||||
|
||||
* time.c (rb_time_magnify): If WIDEVALUE_IS_WIDER, wmul() has the same
|
||||
optimized logic, else mul() has also the similar logic for Fixnum.
|
||||
|
||||
* time.c (rb_time_unmagnify): almost ditto.
|
||||
|
||||
Tue Mar 22 03:10:09 2016 NARUSE, Yui <naruse@ruby-lang.org>
|
||||
|
||||
* time.c (divmodv): add the case both arguments are Fixnum.
|
||||
|
71
time.c
71
time.c
@ -203,6 +203,7 @@ divmodv(VALUE n, VALUE d, VALUE *q, VALUE *r)
|
||||
#define POSFIXWVABLE(wi) ((wi) < FIXWV_MAX+1)
|
||||
#define NEGFIXWVABLE(wi) ((wi) >= FIXWV_MIN)
|
||||
#define FIXWV_P(w) FIXWINT_P(WIDEVAL_GET(w))
|
||||
#define MUL_OVERFLOW_FIXWV_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, FIXWV_MIN, FIXWV_MAX)
|
||||
|
||||
/* #define STRUCT_WIDEVAL */
|
||||
#ifdef STRUCT_WIDEVAL
|
||||
@ -358,65 +359,17 @@ wsub(wideval_t wx, wideval_t wy)
|
||||
return v2w(rb_funcall(x, '-', 1, w2v(wy)));
|
||||
}
|
||||
|
||||
static int
|
||||
wi_mul(wideint_t x, wideint_t y, wideint_t *z)
|
||||
{
|
||||
uwideint_t a, b, c;
|
||||
int s;
|
||||
if (x == 0 || y == 0) {
|
||||
*z = 0;
|
||||
return 1;
|
||||
}
|
||||
if (x < 0) {
|
||||
s = -1;
|
||||
a = (uwideint_t)-x;
|
||||
}
|
||||
else {
|
||||
s = 1;
|
||||
a = (uwideint_t)x;
|
||||
}
|
||||
if (y < 0) {
|
||||
s = -s;
|
||||
b = (uwideint_t)-y;
|
||||
}
|
||||
else {
|
||||
b = (uwideint_t)y;
|
||||
}
|
||||
if (a <= UWIDEINT_MAX / b) {
|
||||
c = a * b;
|
||||
if (s < 0) {
|
||||
if (c <= (uwideint_t)WIDEINT_MAX + 1) {
|
||||
*z = -(wideint_t)c;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (c <= (uwideint_t)WIDEINT_MAX) {
|
||||
*z = (wideint_t)c;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static wideval_t
|
||||
wmul(wideval_t wx, wideval_t wy)
|
||||
{
|
||||
#if WIDEVALUE_IS_WIDER
|
||||
if (FIXWV_P(wx) && FIXWV_P(wy)) {
|
||||
wideint_t z;
|
||||
if (wi_mul(FIXWV2WINT(wx), FIXWV2WINT(wy), &z))
|
||||
return WINT2WV(z);
|
||||
if (MUL_OVERFLOW_FIXWV_P(FIXWV2WINT(wx), FIXWV2WINT(wy))
|
||||
return WINT2WV(FIXWV2WINT(wx) * FIXWV2WINT(wy));
|
||||
}
|
||||
#endif
|
||||
x = w2v(wx);
|
||||
if (RB_TYPE_P(x, T_BIGNUM)) return v2w(rb_big_mul(x, w2v(wy)));
|
||||
z = rb_funcall(x, '*', 1, w2v(wy));
|
||||
if (RB_TYPE_P(z, T_RATIONAL) && RRATIONAL(z)->den == INT2FIX(1)) {
|
||||
z = RRATIONAL(z)->num;
|
||||
}
|
||||
return v2w(z);
|
||||
return v2w(mul(w2v(wx), w2v(wy)));
|
||||
}
|
||||
|
||||
static wideval_t
|
||||
@ -582,28 +535,12 @@ num_exact(VALUE v)
|
||||
static wideval_t
|
||||
rb_time_magnify(wideval_t w)
|
||||
{
|
||||
if (FIXWV_P(w)) {
|
||||
wideint_t z;
|
||||
if (wi_mul(FIXWV2WINT(w), TIME_SCALE, &z))
|
||||
return WINT2WV(z);
|
||||
}
|
||||
return wmul(w, WINT2FIXWV(TIME_SCALE));
|
||||
}
|
||||
|
||||
static wideval_t
|
||||
rb_time_unmagnify(wideval_t w)
|
||||
{
|
||||
#if WIDEVALUE_IS_WIDER
|
||||
if (FIXWV_P(w)) {
|
||||
wideint_t a, b, c;
|
||||
a = FIXWV2WINT(w);
|
||||
b = TIME_SCALE;
|
||||
c = a / b;
|
||||
if (c * b == a) {
|
||||
return WINT2FIXWV(c);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return wquo(w, WINT2FIXWV(TIME_SCALE));
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user