diff options
| author | Paul Eggert | 2019-08-16 16:25:02 -0700 |
|---|---|---|
| committer | Paul Eggert | 2019-08-16 16:27:27 -0700 |
| commit | f9fd12a30b3d94eb48f7b309907d136d7b2682ac (patch) | |
| tree | d00aa93beec6eb1013127ee251342f39f135a994 /test/src | |
| parent | e82923c817159c751aa9c902093a46b9457e8499 (diff) | |
| download | emacs-f9fd12a30b3d94eb48f7b309907d136d7b2682ac.tar.gz emacs-f9fd12a30b3d94eb48f7b309907d136d7b2682ac.zip | |
Fix time-add rounding bug
Without this fix, time arithmetic yielded results that were not
mathematically accurate, even though the exact results were
representable; for example, (time-add 0 1e-13) yielded a timestamp
equal to 0 instead of to 1e-13.
* lisp/timezone.el (timezone-time-from-absolute):
Let time-add do its thing rather than using floating point
internally, which has rounding errors. We now have bignums and so
don’t need floating point to avoid overflow issues.
* src/timefns.c (timeform_sub_ps_p): New function.
(time_arith): If either argument is a float, represent the
result exactly instead of discarding sub-ps info.
* test/lisp/timezone-tests.el (timezone-tests-time-from-absolute):
Don’t assume (HI LO US PS) timestamp format.
* test/src/emacs-module-tests.el (mod-test-add-nanosecond/valid):
Don’t assume that time-add discards sub-ns info.
* test/src/timefns-tests.el (time-rounding-tests):
Add regression test to detect time-add rounding bug.
Diffstat (limited to 'test/src')
| -rw-r--r-- | test/src/emacs-module-tests.el | 7 | ||||
| -rw-r--r-- | test/src/timefns-tests.el | 3 |
2 files changed, 8 insertions, 2 deletions
diff --git a/test/src/emacs-module-tests.el b/test/src/emacs-module-tests.el index c44c386d30b..c5107847318 100644 --- a/test/src/emacs-module-tests.el +++ b/test/src/emacs-module-tests.el | |||
| @@ -335,12 +335,15 @@ Interactively, you can try hitting \\[keyboard-quit] to quit." | |||
| 335 | ;; New (TICKS . HZ) format. | 335 | ;; New (TICKS . HZ) format. |
| 336 | '(123456789 . 1000000000))) | 336 | '(123456789 . 1000000000))) |
| 337 | (ert-info ((format "input: %s" input)) | 337 | (ert-info ((format "input: %s" input)) |
| 338 | (let ((result (mod-test-add-nanosecond input))) | 338 | (let ((result (mod-test-add-nanosecond input)) |
| 339 | (desired-result | ||
| 340 | (let ((hz 1000000000)) | ||
| 341 | (time-add (time-convert input hz) (cons 1 hz))))) | ||
| 339 | (should (consp result)) | 342 | (should (consp result)) |
| 340 | (should (integerp (car result))) | 343 | (should (integerp (car result))) |
| 341 | (should (integerp (cdr result))) | 344 | (should (integerp (cdr result))) |
| 342 | (should (cl-plusp (cdr result))) | 345 | (should (cl-plusp (cdr result))) |
| 343 | (should (time-equal-p result (time-add input '(0 0 0 1000)))))))) | 346 | (should (time-equal-p result desired-result)))))) |
| 344 | 347 | ||
| 345 | (ert-deftest mod-test-add-nanosecond/nil () | 348 | (ert-deftest mod-test-add-nanosecond/nil () |
| 346 | (should (<= (float-time (mod-test-add-nanosecond nil)) | 349 | (should (<= (float-time (mod-test-add-nanosecond nil)) |
diff --git a/test/src/timefns-tests.el b/test/src/timefns-tests.el index 1b1032deaa1..362e7655a91 100644 --- a/test/src/timefns-tests.el +++ b/test/src/timefns-tests.el | |||
| @@ -145,6 +145,9 @@ | |||
| 145 | (< 0.99 (/ (- (float-time a)) (float-time b)) | 145 | (< 0.99 (/ (- (float-time a)) (float-time b)) |
| 146 | 1.01)))))))) | 146 | 1.01)))))))) |
| 147 | 147 | ||
| 148 | (ert-deftest time-rounding-tests () | ||
| 149 | (should (time-equal-p 1e-13 (time-add 0 1e-13)))) | ||
| 150 | |||
| 148 | (ert-deftest encode-time-dst-numeric-zone () | 151 | (ert-deftest encode-time-dst-numeric-zone () |
| 149 | "Check for Bug#35502." | 152 | "Check for Bug#35502." |
| 150 | (should (time-equal-p | 153 | (should (time-equal-p |