diff options
| author | Paul Eggert | 2018-09-05 16:19:47 -0700 |
|---|---|---|
| committer | Paul Eggert | 2018-09-05 16:21:42 -0700 |
| commit | 67475a59e95919e2dbe25ae950450578afdfd0dc (patch) | |
| tree | 2f5f53e83399678e19f3895383f057e032a1609b | |
| parent | e932395656b80cc30ba3a53d83bddf57339aef7d (diff) | |
| download | emacs-67475a59e95919e2dbe25ae950450578afdfd0dc.tar.gz emacs-67475a59e95919e2dbe25ae950450578afdfd0dc.zip | |
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.
| -rw-r--r-- | lisp/emacs-lisp/timer.el | 10 | ||||
| -rw-r--r-- | test/lisp/emacs-lisp/timer-tests.el | 5 |
2 files changed, 10 insertions, 5 deletions
diff --git a/lisp/emacs-lisp/timer.el b/lisp/emacs-lisp/timer.el index 795554fec58..74d37b0eaed 100644 --- a/lisp/emacs-lisp/timer.el +++ b/lisp/emacs-lisp/timer.el | |||
| @@ -102,14 +102,14 @@ fire each time Emacs is idle for that many seconds." | |||
| 102 | "Yield the next value after TIME that is an integral multiple of SECS. | 102 | "Yield the next value after TIME that is an integral multiple of SECS. |
| 103 | More precisely, the next value, after TIME, that is an integral multiple | 103 | More precisely, the next value, after TIME, that is an integral multiple |
| 104 | of SECS seconds since the epoch. SECS may be a fraction." | 104 | of SECS seconds since the epoch. SECS may be a fraction." |
| 105 | (let* ((trillion 1e12) | 105 | (let* ((trillion 1000000000000) |
| 106 | (time-sec (+ (nth 1 time) | 106 | (time-sec (+ (nth 1 time) |
| 107 | (* 65536.0 (nth 0 time)))) | 107 | (* 65536 (nth 0 time)))) |
| 108 | (delta-sec (mod (- time-sec) secs)) | 108 | (delta-sec (mod (- time-sec) secs)) |
| 109 | (next-sec (+ time-sec (ffloor delta-sec))) | 109 | (next-sec (+ time-sec (floor delta-sec))) |
| 110 | (next-sec-psec (ffloor (* trillion (mod delta-sec 1)))) | 110 | (next-sec-psec (floor (* trillion (mod delta-sec 1)))) |
| 111 | (sub-time-psec (+ (or (nth 3 time) 0) | 111 | (sub-time-psec (+ (or (nth 3 time) 0) |
| 112 | (* 1e6 (nth 2 time)))) | 112 | (* 1000000 (nth 2 time)))) |
| 113 | (psec-diff (- sub-time-psec next-sec-psec))) | 113 | (psec-diff (- sub-time-psec next-sec-psec))) |
| 114 | (if (and (<= next-sec time-sec) (< 0 psec-diff)) | 114 | (if (and (<= next-sec time-sec) (< 0 psec-diff)) |
| 115 | (setq next-sec-psec (+ sub-time-psec | 115 | (setq next-sec-psec (+ sub-time-psec |
diff --git a/test/lisp/emacs-lisp/timer-tests.el b/test/lisp/emacs-lisp/timer-tests.el index 65e5dc9bde9..fa92c1b64aa 100644 --- a/test/lisp/emacs-lisp/timer-tests.el +++ b/test/lisp/emacs-lisp/timer-tests.el | |||
| @@ -39,4 +39,9 @@ | |||
| 39 | (if (fboundp 'debug-timer-check) | 39 | (if (fboundp 'debug-timer-check) |
| 40 | (should (debug-timer-check)) t)) | 40 | (should (debug-timer-check)) t)) |
| 41 | 41 | ||
| 42 | (ert-deftest timer-test-multiple-of-time () | ||
| 43 | (should (equal | ||
| 44 | (timer-next-integral-multiple-of-time '(0 0 0 1) (1+ (ash 1 53))) | ||
| 45 | (list (ash 1 (- 53 16)) 1 0 0)))) | ||
| 46 | |||
| 42 | ;;; timer-tests.el ends here | 47 | ;;; timer-tests.el ends here |