From: Paul Eggert Date: Sun, 8 Mar 2020 23:57:41 +0000 (-0700) Subject: Merge from origin/emacs-27 X-Git-Tag: emacs-28.0.90~7782 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=a461baae79af3cea8780e9d9a845a1e859e96e5e;p=emacs.git Merge from origin/emacs-27 cf223dc928 ; * src/timefns.c: Fix typo in previous change. 20d3d3a950 * src/timefns.c: Add comments. --- a461baae79af3cea8780e9d9a845a1e859e96e5e diff --cc src/timefns.c index 6dd6e1611a4,553daf6e6a9..404ce4973b7 --- a/src/timefns.c +++ b/src/timefns.c @@@ -582,27 -597,27 +597,29 @@@ 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; + /* Compute number of base-FLT_RADIX digits in numerator and denominator. */ mpz_t const *n = bignum_integer (&mpz[0], numerator); mpz_t const *d = bignum_integer (&mpz[1], denominator); - ptrdiff_t nbits = mpz_sizeinbase (*n, 2); - ptrdiff_t dbits = mpz_sizeinbase (*d, 2); - eassume (0 < nbits); - eassume (0 < dbits); - ptrdiff_t ndig = (nbits + LOG2_FLT_RADIX - 1) / LOG2_FLT_RADIX; - ptrdiff_t ddig = (dbits + LOG2_FLT_RADIX - 1) / LOG2_FLT_RADIX; + 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, - then divide the double by FLT_RADIX**SCALE. */ + then divide the double by FLT_RADIX**SCALE. First scale N + (or scale D, if SCALE is negative) ... */ - ptrdiff_t scale = ddig - ndig + DBL_MANT_DIG + 1; + ptrdiff_t scale = ddig - ndig + DBL_MANT_DIG; if (scale < 0) { mpz_mul_2exp (mpz[1], *d, - (scale * LOG2_FLT_RADIX));