emacs-diffs
[Top][All Lists]
Advanced

[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)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]