[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master c4bacb1: Clarify rounding mode when converting to s
From: |
Philipp Stephani |
Subject: |
[Emacs-diffs] master c4bacb1: Clarify rounding mode when converting to struct timespec. |
Date: |
Wed, 24 Apr 2019 07:41:49 -0400 (EDT) |
branch: master
commit c4bacb1215bfdf058b374312256c27eaea1304a4
Author: Philipp Stephani <address@hidden>
Commit: Philipp Stephani <address@hidden>
Clarify rounding mode when converting to struct timespec.
* doc/lispref/internals.texi (Module Values): Clarify that the
truncation is towards negative infinity.
* test/data/emacs-module/mod-test.c (Fmod_test_nanoseconds): Add test
function.
(emacs_module_init): Define it.
* test/src/emacs-module-tests.el (mod-test-nanoseconds): New unit test.
---
doc/lispref/internals.texi | 12 ++++++------
test/data/emacs-module/mod-test.c | 17 +++++++++++++++++
test/src/emacs-module-tests.el | 19 +++++++++++++++++++
3 files changed, 42 insertions(+), 6 deletions(-)
diff --git a/doc/lispref/internals.texi b/doc/lispref/internals.texi
index 10f49c5..3e6488a 100644
--- a/doc/lispref/internals.texi
+++ b/doc/lispref/internals.texi
@@ -1406,12 +1406,12 @@ billion.
@xref{Elapsed Time,,,libc}.
If @var{time} has higher precision than nanoseconds, then this
-function truncates it to nanosecond precision. This function signals
-an error if @var{time} (truncated to nanoseconds) cannot be
-represented by @code{struct timespec}. For example, if @code{time_t}
-is a 32-bit integral type, then a @var{time} value of ten billion
-seconds would signal an error, but a @var{time} value of 600
-picoseconds would get truncated to zero.
+function truncates it to nanosecond precision towards negative
+infinity. This function signals an error if @var{time} (truncated to
+nanoseconds) cannot be represented by @code{struct timespec}. For
+example, if @code{time_t} is a 32-bit integral type, then a @var{time}
+value of ten billion seconds would signal an error, but a @var{time}
+value of 600 picoseconds would get truncated to zero.
If you need to deal with time values that are not representable by
@code{struct timespec}, or if you want higher precision, call the Lisp
diff --git a/test/data/emacs-module/mod-test.c
b/test/data/emacs-module/mod-test.c
index 85a7f28..8ac08f7 100644
--- a/test/data/emacs-module/mod-test.c
+++ b/test/data/emacs-module/mod-test.c
@@ -382,6 +382,22 @@ Fmod_test_add_nanosecond (emacs_env *env, ptrdiff_t nargs,
emacs_value *args,
}
static emacs_value
+Fmod_test_nanoseconds (emacs_env *env, ptrdiff_t nargs, emacs_value *args,
void *data) {
+ assert (nargs == 1);
+ struct timespec time = env->extract_time (env, args[0]);
+ struct emacs_mpz nanoseconds;
+ assert (LONG_MIN <= time.tv_sec && time.tv_sec <= LONG_MAX);
+ mpz_init_set_si (nanoseconds.value, time.tv_sec);
+ static_assert (1000000000 <= ULONG_MAX, "unsupported architecture");
+ mpz_mul_ui (nanoseconds.value, nanoseconds.value, 1000000000);
+ assert (0 <= time.tv_nsec && time.tv_nsec <= ULONG_MAX);
+ mpz_add_ui (nanoseconds.value, nanoseconds.value, time.tv_nsec);
+ emacs_value result = env->make_big_integer (env, &nanoseconds);
+ mpz_clear (nanoseconds.value);
+ return result;
+}
+
+static emacs_value
Fmod_test_double (emacs_env *env, ptrdiff_t nargs, emacs_value *args,
void *data)
{
@@ -465,6 +481,7 @@ emacs_module_init (struct emacs_runtime *ert)
NULL, NULL);
DEFUN ("mod-test-sleep-until", Fmod_test_sleep_until, 2, 2, NULL, NULL);
DEFUN ("mod-test-add-nanosecond", Fmod_test_add_nanosecond, 1, 1, NULL,
NULL);
+ DEFUN ("mod-test-nanoseconds", Fmod_test_nanoseconds, 1, 1, NULL, NULL);
DEFUN ("mod-test-double", Fmod_test_double, 1, 1, NULL, NULL);
#undef DEFUN
diff --git a/test/src/emacs-module-tests.el b/test/src/emacs-module-tests.el
index 9eb38cd..173b636 100644
--- a/test/src/emacs-module-tests.el
+++ b/test/src/emacs-module-tests.el
@@ -342,6 +342,25 @@ Interactively, you can try hitting \\[keyboard-quit] to
quit."
(ert-info ((format "input: %s" input))
(should-error (mod-test-add-nanosecond input)))))
+(ert-deftest mod-test-nanoseconds ()
+ "Test truncation when converting to `struct timespec'."
+ (dolist (test-case '((0 . 0)
+ (-1 . -1000000000)
+ ((1 . 1000000000) . 1)
+ ((-1 . 1000000000) . -1)
+ ((1 . 1000000000000) . 0)
+ ((-1 . 1000000000000) . -1)
+ ((999 . 1000000000000) . 0)
+ ((-999 . 1000000000000) . -1)
+ ((1000 . 1000000000000) . 1)
+ ((-1000 . 1000000000000) . -1)
+ ((0 0 0 1) . 0)
+ ((0 0 0 -1) . -1)))
+ (let ((input (car test-case))
+ (expected (cdr test-case)))
+ (ert-info ((format "input: %S, expected result: %d" input expected))
+ (should (eq (mod-test-nanoseconds input) expected))))))
+
(ert-deftest mod-test-double ()
(dolist (input (list 0 1 2 -1 42 12345678901234567890
most-positive-fixnum (1+ most-positive-fixnum)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] master c4bacb1: Clarify rounding mode when converting to struct timespec.,
Philipp Stephani <=