diff --git a/test/unit/util.c b/test/unit/util.c index ef4a596..982a0ce 100644 --- a/test/unit/util.c +++ b/test/unit/util.c @@ -508,9 +508,18 @@ test_unit(void) TEST_CHECK(UTI_DoubleToNtp32(65536.0) == htonl(0xffffffff)); TEST_CHECK(UTI_DoubleToNtp32(65537.0) == htonl(0xffffffff)); + TEST_CHECK(UTI_DoubleToNtp32f28(-1.0) == htonl(0)); + TEST_CHECK(UTI_DoubleToNtp32f28(0.0) == htonl(0)); + TEST_CHECK(UTI_DoubleToNtp32f28(1e-9) == htonl(1)); + TEST_CHECK(UTI_DoubleToNtp32f28(4e-9) == htonl(2)); + TEST_CHECK(UTI_DoubleToNtp32f28(8.0) == htonl(0x80000000)); + TEST_CHECK(UTI_DoubleToNtp32f28(16.0) == htonl(0xffffffff)); + TEST_CHECK(UTI_DoubleToNtp32f28(16.1) == htonl(0xffffffff)); + for (i = 0; i < 100000; i++) { UTI_GetRandomBytes(&ntp32_ts, sizeof (ntp32_ts)); TEST_CHECK(UTI_DoubleToNtp32(UTI_Ntp32ToDouble(ntp32_ts)) == ntp32_ts); + TEST_CHECK(UTI_DoubleToNtp32f28(UTI_Ntp32f28ToDouble(ntp32_ts)) == ntp32_ts); } ts.tv_nsec = 0; diff --git a/util.c b/util.c index 82f8de7..1f66480 100644 --- a/util.c +++ b/util.c @@ -637,6 +637,37 @@ UTI_DoubleToNtp32(double x) /* ================================================== */ +double +UTI_Ntp32f28ToDouble(NTP_int32 x) +{ + return ntohl(x) / (double)(1U << 28); +} + +/* ================================================== */ + +NTP_int32 +UTI_DoubleToNtp32f28(double x) +{ + NTP_int32 r; + + if (x >= 4294967295.0 / (1U << 28)) { + r = 0xffffffff; + } else if (x <= 0.0) { + r = 0; + } else { + x *= 1U << 28; + r = x; + + /* Round up */ + if (r < x) + r++; + } + + return htonl(r); +} + +/* ================================================== */ + void UTI_ZeroNtp64(NTP_int64 *ts) { diff --git a/util.h b/util.h index 434a9b4..f6bf7b9 100644 --- a/util.h +++ b/util.h @@ -133,6 +133,9 @@ extern void UTI_GetNtp64Fuzz(NTP_int64 *ts, int precision); extern double UTI_Ntp32ToDouble(NTP_int32 x); extern NTP_int32 UTI_DoubleToNtp32(double x); +extern double UTI_Ntp32f28ToDouble(NTP_int32 x); +extern NTP_int32 UTI_DoubleToNtp32f28(double x); + /* Zero an NTP timestamp */ extern void UTI_ZeroNtp64(NTP_int64 *ts);