diff options
| author | Paul Eggert | 2020-03-03 10:17:34 -0800 |
|---|---|---|
| committer | Paul Eggert | 2020-03-03 10:20:33 -0800 |
| commit | b48142ba190c5b490685af961af1f0f4fd5440ae (patch) | |
| tree | 99828fdb2da84b04b3dcbbf90816de2c4d3cd325 /src | |
| parent | 5e229f88f946c9c246966defeb629965f65d9549 (diff) | |
| download | emacs-b48142ba190c5b490685af961af1f0f4fd5440ae.tar.gz emacs-b48142ba190c5b490685af961af1f0f4fd5440ae.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/timefns.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/src/timefns.c b/src/timefns.c index b96a6cb8875..0aa8775f9ff 100644 --- a/src/timefns.c +++ b/src/timefns.c | |||
| @@ -569,16 +569,22 @@ timespec_to_lisp (struct timespec t) | |||
| 569 | static double | 569 | static double |
| 570 | frac_to_double (Lisp_Object numerator, Lisp_Object denominator) | 570 | frac_to_double (Lisp_Object numerator, Lisp_Object denominator) |
| 571 | { | 571 | { |
| 572 | intmax_t intmax_numerator; | 572 | intmax_t intmax_numerator, intmax_denominator; |
| 573 | if (FASTER_TIMEFNS && EQ (denominator, make_fixnum (1)) | 573 | if (FASTER_TIMEFNS |
| 574 | && integer_to_intmax (numerator, &intmax_numerator)) | 574 | && integer_to_intmax (numerator, &intmax_numerator) |
| 575 | return intmax_numerator; | 575 | && integer_to_intmax (denominator, &intmax_denominator) |
| 576 | && ! INT_DIVIDE_OVERFLOW (intmax_numerator, intmax_denominator) | ||
| 577 | && intmax_numerator % intmax_denominator == 0) | ||
| 578 | return intmax_numerator / intmax_denominator; | ||
| 576 | 579 | ||
| 577 | mpz_t const *n = bignum_integer (&mpz[0], numerator); | 580 | mpz_t const *n = bignum_integer (&mpz[0], numerator); |
| 578 | mpz_t const *d = bignum_integer (&mpz[1], denominator); | 581 | mpz_t const *d = bignum_integer (&mpz[1], denominator); |
| 579 | ptrdiff_t ndig = mpz_sizeinbase (*n, FLT_RADIX); | 582 | ptrdiff_t ndig = mpz_sizeinbase (*n, FLT_RADIX); |
| 580 | ptrdiff_t ddig = mpz_sizeinbase (*d, FLT_RADIX); | 583 | ptrdiff_t ddig = mpz_sizeinbase (*d, FLT_RADIX); |
| 581 | 584 | ||
| 585 | if (FASTER_TIMEFNS && ndig <= DBL_MANT_DIG && ddig <= DBL_MANT_DIG) | ||
| 586 | return mpz_get_d (*n) / mpz_get_d (*d); | ||
| 587 | |||
| 582 | /* Scale with SCALE when doing integer division. That is, compute | 588 | /* Scale with SCALE when doing integer division. That is, compute |
| 583 | (N * FLT_RADIX**SCALE) / D [or, if SCALE is negative, N / (D * | 589 | (N * FLT_RADIX**SCALE) / D [or, if SCALE is negative, N / (D * |
| 584 | FLT_RADIX**-SCALE)] as a bignum, convert the bignum to double, | 590 | FLT_RADIX**-SCALE)] as a bignum, convert the bignum to double, |