> Yes except for the last sentence. C23 says the final cast is undefined
> when d >= MAX(time_t)+1:
that, if time_t is 64 bit, will happen in 500E9 years. I think we can
accept the risk.
> Well, I completely agree that involving time_t is unnecessary and also
> confusing.
My personal and not proved opinion, is that in this case the best way to
get the integer part of d is casting the double to uint64_t: the integer
part of our double is now only 33bit. Casting to uint is a common
operation, everybody use it, (think to) understand it, and it is good
optimized even if the hardware has no floating point support.
I personally find modf and fmod exotic functions. I had to check the
documentation to learn what they do. If they are not used as low level
support for some common functionality, I suppose they are probably also
not good optimized.
Then casting the uint64_t to uint32_t is a well defined operation.
The only point is that dropping of the bit 33 is not documented. We
have to make it explicit with a comment.
>
> But I think that a guard is needed when converting the double to uint32,
> instead of relying on the UB wraparound. Something like this:
>
> static NOINLINE void
> d_to_lfp(l_fixedpt_t *lfp, double d)
> {
> double di, df;
>
> di = modf(d, &df);
> /* lfp->int_partl = fmod(di, 0x100000000); */
> lfp->int_partl = di < 0x100000000 ? di : di - 0x100000000;
> lfp->fractionl = df * 0x100000000;
> }
>
> static NOINLINE double
> lfp_to_d(l_fixedpt_t lfp)
> {
> /* Treat truncated timestamps from the first half of an era
> as
> * belonging to Era 1, and those from the second half as
> * belonging to Era 0. This works for timestamps generated
> This should be fine, because (time_t)0 maps to NTP timestamp 0x83aa_7e80
> which is safely within the 1968-2036 era, it is unaliased in the lfp
> representation.
This means no problem up to 2104.
_______________________________________________
busybox mailing list
[email protected]
https://lists.busybox.net/mailman/listinfo/busybox