[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master b48142b 2/2: Time division speedups
From: |
Paul Eggert |
Subject: |
master b48142b 2/2: Time division speedups |
Date: |
Tue, 3 Mar 2020 13:20:39 -0500 (EST) |
branch: master
commit b48142ba190c5b490685af961af1f0f4fd5440ae
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>
Time division speedups
* src/timefns.c (frac_to_double) [FASTER_TIMEFNS]: Prefer intmax_t
division or double division to mpz division if they also yield the
correctly rounded result.
---
src/timefns.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/src/timefns.c b/src/timefns.c
index b96a6cb..0aa8775 100644
--- a/src/timefns.c
+++ b/src/timefns.c
@@ -569,16 +569,22 @@ timespec_to_lisp (struct timespec t)
static double
frac_to_double (Lisp_Object numerator, Lisp_Object denominator)
{
- intmax_t intmax_numerator;
- if (FASTER_TIMEFNS && EQ (denominator, make_fixnum (1))
- && integer_to_intmax (numerator, &intmax_numerator))
- return intmax_numerator;
+ intmax_t intmax_numerator, intmax_denominator;
+ if (FASTER_TIMEFNS
+ && integer_to_intmax (numerator, &intmax_numerator)
+ && integer_to_intmax (denominator, &intmax_denominator)
+ && ! INT_DIVIDE_OVERFLOW (intmax_numerator, intmax_denominator)
+ && intmax_numerator % intmax_denominator == 0)
+ return intmax_numerator / intmax_denominator;
mpz_t const *n = bignum_integer (&mpz[0], numerator);
mpz_t const *d = bignum_integer (&mpz[1], denominator);
ptrdiff_t ndig = mpz_sizeinbase (*n, FLT_RADIX);
ptrdiff_t ddig = mpz_sizeinbase (*d, FLT_RADIX);
+ if (FASTER_TIMEFNS && ndig <= DBL_MANT_DIG && ddig <= DBL_MANT_DIG)
+ return mpz_get_d (*n) / mpz_get_d (*d);
+
/* Scale with SCALE when doing integer division. That is, compute
(N * FLT_RADIX**SCALE) / D [or, if SCALE is negative, N / (D *
FLT_RADIX**-SCALE)] as a bignum, convert the bignum to double,