Fix timer.el minor rounding error

* lisp/emacs-lisp/timer.el (timer-next-integral-multiple-of-time):
Fix rounding error by using integers rather than floats.
* test/lisp/emacs-lisp/timer-tests.el (timer-test-multiple-of-time):
New test.
This commit is contained in:
Paul Eggert 2018-09-05 16:19:47 -07:00 committed by Paul Eggert
parent e932395656
commit 67475a59e9
2 changed files with 10 additions and 5 deletions

View file

@ -102,14 +102,14 @@ fire each time Emacs is idle for that many seconds."
"Yield the next value after TIME that is an integral multiple of SECS.
More precisely, the next value, after TIME, that is an integral multiple
of SECS seconds since the epoch. SECS may be a fraction."
(let* ((trillion 1e12)
(let* ((trillion 1000000000000)
(time-sec (+ (nth 1 time)
(* 65536.0 (nth 0 time))))
(* 65536 (nth 0 time))))
(delta-sec (mod (- time-sec) secs))
(next-sec (+ time-sec (ffloor delta-sec)))
(next-sec-psec (ffloor (* trillion (mod delta-sec 1))))
(next-sec (+ time-sec (floor delta-sec)))
(next-sec-psec (floor (* trillion (mod delta-sec 1))))
(sub-time-psec (+ (or (nth 3 time) 0)
(* 1e6 (nth 2 time))))
(* 1000000 (nth 2 time))))
(psec-diff (- sub-time-psec next-sec-psec)))
(if (and (<= next-sec time-sec) (< 0 psec-diff))
(setq next-sec-psec (+ sub-time-psec

View file

@ -39,4 +39,9 @@
(if (fboundp 'debug-timer-check)
(should (debug-timer-check)) t))
(ert-deftest timer-test-multiple-of-time ()
(should (equal
(timer-next-integral-multiple-of-time '(0 0 0 1) (1+ (ash 1 53)))
(list (ash 1 (- 53 16)) 1 0 0))))
;;; timer-tests.el ends here