xref: /netbsd-src/external/bsd/ntp/dist/libntp/timexsup.c (revision eabc0478de71e4e011a5b4e0392741e01d491794)
1*eabc0478Schristos /*	$NetBSD: timexsup.c,v 1.5 2024/08/18 20:47:13 christos Exp $	*/
2067f5680Schristos 
3067f5680Schristos /*
4067f5680Schristos  * timexsup.c - 'struct timex' support functions
5067f5680Schristos  *
6067f5680Schristos  * Written by Juergen Perlinger (perlinger@ntp.org) for the NTP project.
7067f5680Schristos  * The contents of 'html/copyright.html' apply.
8067f5680Schristos  */
9067f5680Schristos 
10067f5680Schristos #include "config.h"
11067f5680Schristos #include <limits.h>
12067f5680Schristos #include <math.h>
13067f5680Schristos 
14*eabc0478Schristos #ifdef HAVE_SYS_TIME_H
15*eabc0478Schristos # include <sys/time.h>
16*eabc0478Schristos #else
17*eabc0478Schristos # ifdef HAVE_TIME_H
18*eabc0478Schristos #  include <time.h>
19*eabc0478Schristos # endif
20*eabc0478Schristos #endif
21067f5680Schristos #ifdef HAVE_SYS_TIMEX_H
22cdfa2a7eSchristos # include <time.h>
23067f5680Schristos # include <sys/timex.h>
24*eabc0478Schristos #else
25*eabc0478Schristos # ifdef HAVE_TIMEX_H
26*eabc0478Schristos #  include <timex.h>
27067f5680Schristos # endif
28*eabc0478Schristos #endif
29*eabc0478Schristos 
30*eabc0478Schristos #include "ntp_types.h"
31*eabc0478Schristos #include "timexsup.h"
32067f5680Schristos 
33067f5680Schristos #if defined(MOD_NANO) != defined(STA_NANO)
34067f5680Schristos # warning inconsistent definitions of MOD_NANO vs STA_NANO
35067f5680Schristos #endif
36067f5680Schristos 
37067f5680Schristos static long
38067f5680Schristos clamp_rounded(
39067f5680Schristos 	double dval
40067f5680Schristos 	)
41067f5680Schristos {
42067f5680Schristos 	/* round */
43067f5680Schristos 	dval = floor(dval + 0.5);
44067f5680Schristos 
45067f5680Schristos 	/* clamp / saturate */
461c87ec2cSchristos 	if (dval >= (double)LONG_MAX)
47067f5680Schristos 		return LONG_MAX;
481c87ec2cSchristos 	if (dval <= (double)LONG_MIN)
49067f5680Schristos 		return LONG_MIN;
50067f5680Schristos 	return (long)dval;
51067f5680Schristos }
5250c1baceSchristos 
53067f5680Schristos double
54067f5680Schristos dbl_from_var_long(
55067f5680Schristos 	long	lval,
56067f5680Schristos 	int	status
57067f5680Schristos 	)
58067f5680Schristos {
59067f5680Schristos #ifdef STA_NANO
60*eabc0478Schristos 	if (STA_NANO & status) {
61067f5680Schristos 		return (double)lval * 1e-9;
62*eabc0478Schristos 	}
63067f5680Schristos #else
64*eabc0478Schristos 	UNUSED_ARG(status);
65067f5680Schristos #endif
66067f5680Schristos 	return (double)lval * 1e-6;
67067f5680Schristos }
68067f5680Schristos 
69067f5680Schristos double
70067f5680Schristos dbl_from_usec_long(
71067f5680Schristos 	long	lval
72067f5680Schristos 	)
73067f5680Schristos {
74067f5680Schristos 	return (double)lval * 1e-6;
75067f5680Schristos }
76067f5680Schristos 
77067f5680Schristos long
78067f5680Schristos var_long_from_dbl(
79067f5680Schristos 	double		dval,
80067f5680Schristos 	unsigned int *	modes
81067f5680Schristos 	)
82067f5680Schristos {
83067f5680Schristos #ifdef MOD_NANO
84067f5680Schristos 	*modes |= MOD_NANO;
85067f5680Schristos 	dval *= 1e+9;
86067f5680Schristos #else
87*eabc0478Schristos 	UNUSED_ARG(modes);
88067f5680Schristos 	dval *= 1e+6;
89067f5680Schristos #endif
90067f5680Schristos 	return clamp_rounded(dval);
91067f5680Schristos }
92067f5680Schristos 
93067f5680Schristos long
94067f5680Schristos usec_long_from_dbl(
95067f5680Schristos 	double	dval
96067f5680Schristos 	)
97067f5680Schristos {
98067f5680Schristos 	return clamp_rounded(dval * 1e+6);
99067f5680Schristos }
100