In GNU Emacs 31.0.50 (build 1, x86_64-w64-mingw32) of 2025-01-10 built on AMIRALIRAJA2ACF Repository revision: 42a5ac3b513ff03c64c9609fc7e79c2b7932b2a4 Repository branch: master System Description: M1 Mac Book Pro running Windows 11 VM using Parallels Configured using: 'configure --enable-checking --prefix=/c/emacs --without-dbus 'CFLAGS=-ggdb3 -O0' LDFLAGS=-ggdb3' Configured features: ACL GIF GMP GNUTLS HARFBUZZ JPEG LCMS2 LIBXML2 MODULES NATIVE_COMP NOTIFY W32NOTIFY PDUMPER PNG RSVG SOUND SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS TREE_SITTER WEBP XPM ZLIB Important settings: value of $LC_CTYPE: en_US.UTF-8 value of $LANG: ENU locale-coding-system: cp1252 Minimum repro: emacs -Q M-x customize-mode Type anything into search box Press Enter Backtrace: addr2line -C -f -i -p -e ./src/emacs.exe < ./emacs_backtrace.txt ?? ??:0 ?? ??:0 ?? ??:0 w32_backtrace at C:/other-projects/emacs/src/w32fns.c:11571 emacs_abort at C:/other-projects/emacs/src/w32fns.c:11610 terminate_due_to_signal at C:/other-projects/emacs/src/emacs.c:464 handle_fatal_signal at C:/other-projects/emacs/src/sysdep.c:1799 deliver_thread_signal at C:/other-projects/emacs/src/sysdep.c:1791 deliver_fatal_thread_signal at C:/other-projects/emacs/src/sysdep.c:1811 ?? ??:0 ?? ??:0 ?? ??:0 ?? ??:0 ?? ??:0 rescale_for_division at C:/other-projects/emacs/src/floatfns.c:387 rounding_driver at C:/other-projects/emacs/src/floatfns.c:442 Ffloor at C:/other-projects/emacs/src/floatfns.c:536 funcall_subr at C:/other-projects/emacs/src/eval.c:3152 exec_byte_code at C:/other-projects/emacs/src/bytecode.c:813 funcall_lambda at C:/other-projects/emacs/src/eval.c:3241 funcall_general at C:/other-projects/emacs/src/eval.c:3033 Ffuncall at C:/other-projects/emacs/src/eval.c:3082 Fapply at C:/other-projects/emacs/src/eval.c:2754 funcall_subr at C:/other-projects/emacs/src/eval.c:3173 funcall_general at C:/other-projects/emacs/src/eval.c:3029 Ffuncall at C:/other-projects/emacs/src/eval.c:3082 ?? ??:0 funcall_subr at C:/other-projects/emacs/src/eval.c:3150 funcall_general at C:/other-projects/emacs/src/eval.c:3029 Ffuncall at C:/other-projects/emacs/src/eval.c:3082 timer_check_2 at C:/other-projects/emacs/src/keyboard.c:4804 timer_check at C:/other-projects/emacs/src/keyboard.c:4869 readable_events at C:/other-projects/emacs/src/keyboard.c:3601 get_input_pending at C:/other-projects/emacs/src/keyboard.c:7872 detect_input_pending_run_timers at C:/other-projects/emacs/src/keyboard.c:11576 wait_reading_process_output at C:/other-projects/emacs/src/process.c:5856 sit_for at C:/other-projects/emacs/src/dispnew.c:6889 read_char at C:/other-projects/emacs/src/keyboard.c:2925 read_key_sequence at C:/other-projects/emacs/src/keyboard.c:10746 command_loop_1 at C:/other-projects/emacs/src/keyboard.c:1424 internal_condition_case at C:/other-projects/emacs/src/eval.c:1603 command_loop_2 at C:/other-projects/emacs/src/keyboard.c:1163 internal_catch at C:/other-projects/emacs/src/eval.c:1286 command_loop at C:/other-projects/emacs/src/keyboard.c:1141 recursive_edit_1 at C:/other-projects/emacs/src/keyboard.c:747 Frecursive_edit at C:/other-projects/emacs/src/keyboard.c:830 main at C:/other-projects/emacs/src/emacs.c:2635 __tmainCRTStartup at C:/M/B/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:266 mainCRTStartup at C:/M/B/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:185 __start at C:/other-projects/emacs/src/w32proc.c:158 ?? ??:0 ?? ??:0 ?? ??:0 Notes: Updating the rounding_driver function in ./src/floatfns.c from Emacs 26 resolved the issue. diff --git a/src/floatfns.c b/src/floatfns.c index 4492815c765..26c2e15da05 100644 --- a/src/floatfns.c +++ b/src/floatfns.c @@ -400,48 +400,79 @@ rescale_for_division (Lisp_Object n, mpz_t *t, int nscale, int dscale) /* the rounding functions */ +static bool +integer_value (Lisp_Object a) +{ + if (FLOATP (a)) + { + double d = XFLOAT_DATA (a); + return d == floor (d) && isfinite (d); + } + return true; +} + static Lisp_Object -rounding_driver (Lisp_Object n, Lisp_Object d, +rounding_driver (Lisp_Object arg, Lisp_Object divisor, double (*double_round) (double), void (*int_divide) (mpz_t, mpz_t const, mpz_t const), EMACS_INT (*fixnum_divide) (EMACS_INT, EMACS_INT)) { - CHECK_NUMBER (n); + CHECK_NUMBER (arg); - if (NILP (d)) - return FLOATP (n) ? double_to_integer (double_round (XFLOAT_DATA (n))) : n; - - CHECK_NUMBER (d); - - int dscale = 0; - if (FIXNUMP (d)) + double d; + if (NILP (divisor)) { - if (XFIXNUM (d) == 0) - xsignal0 (Qarith_error); - - /* Divide fixnum by fixnum specially, for speed. */ - if (FIXNUMP (n)) - return make_int (fixnum_divide (XFIXNUM (n), XFIXNUM (d))); + if (! FLOATP (arg)) + return arg; + d = XFLOAT_DATA (arg); } - else if (FLOATP (d)) + else { - if (XFLOAT_DATA (d) == 0) - xsignal0 (Qarith_error); - dscale = double_integer_scale (XFLOAT_DATA (d)); - } + CHECK_NUMBER (divisor); + if (integer_value (arg) && integer_value (divisor)) + { + /* Divide as integers. Converting to double might lose + info, even for fixnums; also see the FIXME below. */ - int nscale = FLOATP (n) ? double_integer_scale (XFLOAT_DATA (n)) : 0; + if (FLOATP (arg)) + arg = double_to_integer (XFLOAT_DATA (arg)); + if (FLOATP (divisor)) + divisor = double_to_integer (XFLOAT_DATA (divisor)); - /* If the numerator is finite and the denominator infinite, the - quotient is zero and there is no need to try the impossible task - of rescaling the denominator. */ - if (dscale == DBL_MANT_DIG - DBL_MIN_EXP + 1 && nscale < dscale) - return make_fixnum (0); + if (FIXNUMP (divisor)) + { + if (XFIXNUM (divisor) == 0) + xsignal0 (Qarith_error); + if (FIXNUMP (arg)) + return make_int (fixnum_divide (XFIXNUM (arg), + XFIXNUM (divisor))); + } + int_divide (mpz[0], + ,*bignum_integer (&mpz[0], arg), + ,*bignum_integer (&mpz[1], divisor)); + return make_integer_mpz (); + } - int_divide (mpz[0], - *rescale_for_division (n, &mpz[0], nscale, dscale), - *rescale_for_division (d, &mpz[1], dscale, nscale)); - return make_integer_mpz (); + double f1 = XFLOATINT (arg); + double f2 = XFLOATINT (divisor); + if (! IEEE_FLOATING_POINT && f2 == 0) + xsignal0 (Qarith_error); + /* FIXME: This division rounds, so the result is double-rounded. */ + d = f1 / f2; + } + + /* Round, coarsely test for fixnum overflow before converting to + EMACS_INT (to avoid undefined C behavior), and then exactly test + for overflow after converting (as FIXNUM_OVERFLOW_P is inaccurate + on floats). */ + double dr = double_round (d); + if (fabs (dr) < 2 * (MOST_POSITIVE_FIXNUM + 1)) + { + EMACS_INT ir = dr; + if (! FIXNUM_OVERFLOW_P (ir)) + return make_fixnum (ir); + } + return double_to_integer (dr); } static EMACS_INT