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