]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/tzcode/stdtime/difftime.c
amd64: use register macros for gdb_cpu_getreg()
[FreeBSD/FreeBSD.git] / contrib / tzcode / stdtime / difftime.c
1 /*
2 ** This file is in the public domain, so clarified as of
3 ** 1996-06-05 by Arthur David Olson.
4 */
5
6 #include <sys/cdefs.h>
7 #ifndef lint
8 #ifndef NOID
9 static char     elsieid[] __unused = "@(#)difftime.c    8.1";
10 #endif /* !defined NOID */
11 #endif /* !defined lint */
12 __FBSDID("$FreeBSD$");
13
14 /*LINTLIBRARY*/
15
16 #include "namespace.h"
17 #include "private.h"    /* for time_t, TYPE_INTEGRAL, and TYPE_SIGNED */
18 #include "un-namespace.h"
19
20 double
21 difftime(const time_t time1, const time_t time0)
22 {
23         /*
24         ** If (sizeof (double) > sizeof (time_t)) simply convert and subtract
25         ** (assuming that the larger type has more precision).
26         ** This is the common real-world case circa 2004.
27         */
28         if (sizeof (double) > sizeof (time_t))
29                 return (double) time1 - (double) time0;
30         if (!TYPE_INTEGRAL(time_t)) {
31                 /*
32                 ** time_t is floating.
33                 */
34                 return time1 - time0;
35         }
36         if (!TYPE_SIGNED(time_t)) {
37                 /*
38                 ** time_t is integral and unsigned.
39                 ** The difference of two unsigned values can't overflow
40                 ** if the minuend is greater than or equal to the subtrahend.
41                 */
42                 if (time1 >= time0)
43                         return time1 - time0;
44                 else    return -((double) (time0 - time1));
45         }
46         /*
47         ** time_t is integral and signed.
48         ** Handle cases where both time1 and time0 have the same sign
49         ** (meaning that their difference cannot overflow).
50         */
51         if ((time1 < 0) == (time0 < 0))
52                 return time1 - time0;
53         /*
54         ** time1 and time0 have opposite signs.
55         ** Punt if unsigned long is too narrow.
56         */
57         if (sizeof (unsigned long) < sizeof (time_t))
58                 return (double) time1 - (double) time0;
59         /*
60         ** Stay calm...decent optimizers will eliminate the complexity below.
61         */
62         if (time1 >= 0 /* && time0 < 0 */)
63                 return (unsigned long) time1 +
64                         (unsigned long) (-(time0 + 1)) + 1;
65         return -(double) ((unsigned long) time0 +
66                 (unsigned long) (-(time1 + 1)) + 1);
67 }