xref: /freebsd-src/contrib/ntp/libntp/timexsup.c (revision 2d4e511ca269f1908d27f4e5779c53475527391d)
1*2d4e511cSCy Schubert /*
2*2d4e511cSCy Schubert  * timexsup.c - 'struct timex' support functions
3*2d4e511cSCy Schubert  *
4*2d4e511cSCy Schubert  * Written by Juergen Perlinger (perlinger@ntp.org) for the NTP project.
5*2d4e511cSCy Schubert  * The contents of 'html/copyright.html' apply.
6*2d4e511cSCy Schubert  */
7*2d4e511cSCy Schubert 
8*2d4e511cSCy Schubert #include "config.h"
9*2d4e511cSCy Schubert #include "timexsup.h"
10*2d4e511cSCy Schubert #include <limits.h>
11*2d4e511cSCy Schubert #include <math.h>
12*2d4e511cSCy Schubert 
13*2d4e511cSCy Schubert #ifdef HAVE_SYS_TIMEX_H
14*2d4e511cSCy Schubert # include <sys/timex.h>
15*2d4e511cSCy Schubert #endif
16*2d4e511cSCy Schubert 
17*2d4e511cSCy Schubert #if defined(MOD_NANO) != defined(STA_NANO)
18*2d4e511cSCy Schubert # warning inconsistent definitions of MOD_NANO vs STA_NANO
19*2d4e511cSCy Schubert #endif
20*2d4e511cSCy Schubert 
21*2d4e511cSCy Schubert static long
22*2d4e511cSCy Schubert clamp_rounded(
23*2d4e511cSCy Schubert 	double dval
24*2d4e511cSCy Schubert 	)
25*2d4e511cSCy Schubert {
26*2d4e511cSCy Schubert 	/* round */
27*2d4e511cSCy Schubert 	dval = floor(dval + 0.5);
28*2d4e511cSCy Schubert 
29*2d4e511cSCy Schubert 	/* clamp / saturate */
30*2d4e511cSCy Schubert 	if (dval >= LONG_MAX)
31*2d4e511cSCy Schubert 		return LONG_MAX;
32*2d4e511cSCy Schubert 	if (dval <= LONG_MIN)
33*2d4e511cSCy Schubert 		return LONG_MIN;
34*2d4e511cSCy Schubert 	return (long)dval;
35*2d4e511cSCy Schubert 
36*2d4e511cSCy Schubert }
37*2d4e511cSCy Schubert double
38*2d4e511cSCy Schubert dbl_from_var_long(
39*2d4e511cSCy Schubert 	long	lval,
40*2d4e511cSCy Schubert 	int	status
41*2d4e511cSCy Schubert 	)
42*2d4e511cSCy Schubert {
43*2d4e511cSCy Schubert #ifdef STA_NANO
44*2d4e511cSCy Schubert 	if (status & STA_NANO)
45*2d4e511cSCy Schubert 		return (double)lval * 1e-9;
46*2d4e511cSCy Schubert #else
47*2d4e511cSCy Schubert 	(void)status;
48*2d4e511cSCy Schubert #endif
49*2d4e511cSCy Schubert 	return (double)lval * 1e-6;
50*2d4e511cSCy Schubert }
51*2d4e511cSCy Schubert 
52*2d4e511cSCy Schubert double
53*2d4e511cSCy Schubert dbl_from_usec_long(
54*2d4e511cSCy Schubert 	long	lval
55*2d4e511cSCy Schubert 	)
56*2d4e511cSCy Schubert {
57*2d4e511cSCy Schubert 	return (double)lval * 1e-6;
58*2d4e511cSCy Schubert }
59*2d4e511cSCy Schubert 
60*2d4e511cSCy Schubert long
61*2d4e511cSCy Schubert var_long_from_dbl(
62*2d4e511cSCy Schubert 	double		dval,
63*2d4e511cSCy Schubert 	unsigned int *	modes
64*2d4e511cSCy Schubert 	)
65*2d4e511cSCy Schubert {
66*2d4e511cSCy Schubert #ifdef MOD_NANO
67*2d4e511cSCy Schubert 	*modes |= MOD_NANO;
68*2d4e511cSCy Schubert 	dval *= 1e+9;
69*2d4e511cSCy Schubert #else
70*2d4e511cSCy Schubert 	(void)modes;
71*2d4e511cSCy Schubert 	dval *= 1e+6;
72*2d4e511cSCy Schubert #endif
73*2d4e511cSCy Schubert 	return clamp_rounded(dval);
74*2d4e511cSCy Schubert }
75*2d4e511cSCy Schubert 
76*2d4e511cSCy Schubert long
77*2d4e511cSCy Schubert usec_long_from_dbl(
78*2d4e511cSCy Schubert 	double	dval
79*2d4e511cSCy Schubert 	)
80*2d4e511cSCy Schubert {
81*2d4e511cSCy Schubert 	return clamp_rounded(dval * 1e+6);
82*2d4e511cSCy Schubert }
83*2d4e511cSCy Schubert 
84