mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-26 07:33:47 +00:00
time-equal, and time values of infinity and NaN
* doc/lispref/os.texi (Time Calculations): Document time-equal, and the behavior on NaNs and infinities of time-less-p, time-add, time-subtract. * etc/NEWS: Mention the change. * src/editfns.c (time_arith): Change last arg from function to bool. All callers changed. Do the right thing with infinities and NaNs. (time_cmp): New function, which handlesx infinities and NaNs. (Ftime_less_p): Use it. (Ftime_equal): New function. * test/lisp/emacs-lisp/timer-tests.el (timer-test-multiple-of-time): Use it.
This commit is contained in:
parent
21fc322763
commit
06e2814e1f
@ -1736,17 +1736,26 @@ integer number stands for the number of seconds since the epoch.
|
||||
@defun time-less-p t1 t2
|
||||
This returns @code{t} if time value @var{t1} is less than time value
|
||||
@var{t2}.
|
||||
The result is @code{nil} if either argument is a NaN.
|
||||
@end defun
|
||||
|
||||
@defun time-equal t1 t2
|
||||
This returns @code{t} if @var{t1} and @var{t2} are equal time values.
|
||||
The result is @code{nil} if either argument is a NaN.
|
||||
@end defun
|
||||
|
||||
@defun time-subtract t1 t2
|
||||
This returns the time difference @var{t1} @minus{} @var{t2} between
|
||||
two time values, as a time value. If you need the difference in units
|
||||
two time values, as a time value. However, the result is a float
|
||||
if either argument is a float infinity or NaN@.
|
||||
If you need the difference in units
|
||||
of elapsed seconds, use @code{float-time} (@pxref{Time of Day,
|
||||
float-time}) to convert the result into seconds.
|
||||
@end defun
|
||||
|
||||
@defun time-add t1 t2
|
||||
This returns the sum of two time values, as a time value.
|
||||
However, the result is a float if either argument is a float infinity or NaN@.
|
||||
One argument should represent a time difference rather than a point in time,
|
||||
either as a list or as a single number of elapsed seconds.
|
||||
Here is how to add a number of seconds to a time value:
|
||||
|
8
etc/NEWS
8
etc/NEWS
@ -951,6 +951,14 @@ like file-attributes that compute file sizes and other attributes,
|
||||
functions like process-id that compute process IDs, and functions like
|
||||
user-uid and group-gid that compute user and group IDs.
|
||||
|
||||
+++
|
||||
** 'time-add', 'time-subtract', and 'time-less-p' now accept
|
||||
infinities and NaNs too, and propagate them or return nil like
|
||||
floating-point operators do.
|
||||
|
||||
+++
|
||||
** New function 'time-equal' compares time values for equality.
|
||||
|
||||
** define-minor-mode automatically documents the meaning of ARG.
|
||||
|
||||
+++
|
||||
|
@ -1589,13 +1589,21 @@ time_subtract (struct lisp_time ta, struct lisp_time tb)
|
||||
}
|
||||
|
||||
static Lisp_Object
|
||||
time_arith (Lisp_Object a, Lisp_Object b,
|
||||
struct lisp_time (*op) (struct lisp_time, struct lisp_time))
|
||||
time_arith (Lisp_Object a, Lisp_Object b, bool subtract)
|
||||
{
|
||||
if (FLOATP (a) && !isfinite (XFLOAT_DATA (a)))
|
||||
{
|
||||
double da = XFLOAT_DATA (a);
|
||||
double db = XFLOAT_DATA (Ffloat_time (b));
|
||||
return make_float (subtract ? da - db : da + db);
|
||||
}
|
||||
if (FLOATP (b) && !isfinite (XFLOAT_DATA (b)))
|
||||
return subtract ? make_float (-XFLOAT_DATA (b)) : b;
|
||||
|
||||
int alen, blen;
|
||||
struct lisp_time ta = lisp_time_struct (a, &alen);
|
||||
struct lisp_time tb = lisp_time_struct (b, &blen);
|
||||
struct lisp_time t = op (ta, tb);
|
||||
struct lisp_time t = (subtract ? time_subtract : time_add) (ta, tb);
|
||||
if (FIXNUM_OVERFLOW_P (t.hi))
|
||||
time_overflow ();
|
||||
Lisp_Object val = Qnil;
|
||||
@ -1623,7 +1631,7 @@ A nil value for either argument stands for the current time.
|
||||
See `current-time-string' for the various forms of a time value. */)
|
||||
(Lisp_Object a, Lisp_Object b)
|
||||
{
|
||||
return time_arith (a, b, time_add);
|
||||
return time_arith (a, b, false);
|
||||
}
|
||||
|
||||
DEFUN ("time-subtract", Ftime_subtract, Stime_subtract, 2, 2, 0,
|
||||
@ -1633,7 +1641,30 @@ A nil value for either argument stands for the current time.
|
||||
See `current-time-string' for the various forms of a time value. */)
|
||||
(Lisp_Object a, Lisp_Object b)
|
||||
{
|
||||
return time_arith (a, b, time_subtract);
|
||||
return time_arith (a, b, true);
|
||||
}
|
||||
|
||||
/* Return negative, 0, positive if a < b, a == b, a > b respectively.
|
||||
Return positive if either a or b is a NaN; this is good enough
|
||||
for the current callers. */
|
||||
static int
|
||||
time_cmp (Lisp_Object a, Lisp_Object b)
|
||||
{
|
||||
if ((FLOATP (a) && !isfinite (XFLOAT_DATA (a)))
|
||||
|| (FLOATP (b) && !isfinite (XFLOAT_DATA (b))))
|
||||
{
|
||||
double da = FLOATP (a) ? XFLOAT_DATA (a) : 0;
|
||||
double db = FLOATP (b) ? XFLOAT_DATA (b) : 0;
|
||||
return da < db ? -1 : da != db;
|
||||
}
|
||||
|
||||
int alen, blen;
|
||||
struct lisp_time ta = lisp_time_struct (a, &alen);
|
||||
struct lisp_time tb = lisp_time_struct (b, &blen);
|
||||
return (ta.hi != tb.hi ? (ta.hi < tb.hi ? -1 : 1)
|
||||
: ta.lo != tb.lo ? (ta.lo < tb.lo ? -1 : 1)
|
||||
: ta.us != tb.us ? (ta.us < tb.us ? -1 : 1)
|
||||
: ta.ps < tb.ps ? -1 : ta.ps != tb.ps);
|
||||
}
|
||||
|
||||
DEFUN ("time-less-p", Ftime_less_p, Stime_less_p, 2, 2, 0,
|
||||
@ -1642,14 +1673,14 @@ A nil value for either argument stands for the current time.
|
||||
See `current-time-string' for the various forms of a time value. */)
|
||||
(Lisp_Object t1, Lisp_Object t2)
|
||||
{
|
||||
int t1len, t2len;
|
||||
struct lisp_time a = lisp_time_struct (t1, &t1len);
|
||||
struct lisp_time b = lisp_time_struct (t2, &t2len);
|
||||
return ((a.hi != b.hi ? a.hi < b.hi
|
||||
: a.lo != b.lo ? a.lo < b.lo
|
||||
: a.us != b.us ? a.us < b.us
|
||||
: a.ps < b.ps)
|
||||
? Qt : Qnil);
|
||||
return time_cmp (t1, t2) < 0 ? Qt : Qnil;
|
||||
}
|
||||
|
||||
DEFUN ("time-equal", Ftime_equal, Stime_equal, 2, 2, 0,
|
||||
doc: /* Return non-nil if T1 and T2 are equal time values. */)
|
||||
(Lisp_Object t1, Lisp_Object t2)
|
||||
{
|
||||
return time_cmp (t1, t2) == 0 ? Qt : Qnil;
|
||||
}
|
||||
|
||||
|
||||
@ -5734,6 +5765,7 @@ it to be non-nil. */);
|
||||
defsubr (&Scurrent_time);
|
||||
defsubr (&Stime_add);
|
||||
defsubr (&Stime_subtract);
|
||||
defsubr (&Stime_equal);
|
||||
defsubr (&Stime_less_p);
|
||||
defsubr (&Sget_internal_run_time);
|
||||
defsubr (&Sformat_time_string);
|
||||
|
@ -40,10 +40,8 @@
|
||||
(should (debug-timer-check)) t))
|
||||
|
||||
(ert-deftest timer-test-multiple-of-time ()
|
||||
(should (zerop
|
||||
(float-time
|
||||
(time-subtract
|
||||
(timer-next-integral-multiple-of-time '(0 0 0 1) (1+ (ash 1 53)))
|
||||
(list (ash 1 (- 53 16)) 1))))))
|
||||
(should (time-equal
|
||||
(timer-next-integral-multiple-of-time '(0 0 0 1) (1+ (ash 1 53)))
|
||||
(list (ash 1 (- 53 16)) 1))))
|
||||
|
||||
;;; timer-tests.el ends here
|
||||
|
Loading…
Reference in New Issue
Block a user