Paul Eggert wrote: > * lib/timespec.h (dtotimespec): New decl. > * lib/dtotimespec.c, modules/dtotimespec: New files. > --- > ChangeLog | 4 +++ > lib/dtotimespec.c | 69 > +++++++++++++++++++++++++++++++++++++++++++++++++++ > lib/timespec.h | 2 + > modules/dtotimespec | 25 ++++++++++++++++++ > 4 files changed, 100 insertions(+), 0 deletions(-) > create mode 100644 lib/dtotimespec.c > create mode 100644 modules/dtotimespec > > diff --git a/ChangeLog b/ChangeLog > index 0f37252..d20588f 100644 > --- a/ChangeLog > +++ b/ChangeLog > @@ -1,5 +1,9 @@ > 2011-06-30 Paul Eggert <egg...@cs.ucla.edu> > > + dtotimespec: new module > + * lib/timespec.h (dtotimespec): New decl. > + * lib/dtotimespec.c, modules/dtotimespec: New files. > + > * lib/timespec.h (timespec_sign, timespectod): New inline functions. > > pselect: new module > diff --git a/lib/dtotimespec.c b/lib/dtotimespec.c ... > +struct timespec > +dtotimespec (double sec) > +{ > + enum { BILLION = 1000 * 1000 * 1000 }; > + double min_representable = TYPE_MINIMUM (time_t); > + double max_representable = > + ((TYPE_MAXIMUM (time_t) * (double) BILLION + (BILLION - 1)) > + / BILLION); > + struct timespec r;
Nice work. Not surprisingly, I found no way to make it misbehave. > + if (! (min_representable < sec)) > + { > + r.tv_sec = TYPE_MINIMUM (time_t); > + r.tv_nsec = 0; > + } > + else if (! (sec < max_representable)) > + { > + r.tv_sec = TYPE_MAXIMUM (time_t); > + r.tv_nsec = BILLION - 1; > + } > + else > + { > + time_t s = sec; > + double frac = BILLION * (sec - s); > + long ns = frac; > + ns += ns < frac; > + s += ns / BILLION; > + ns %= BILLION; > + > + if (ns < 0) > + { > + s--; > + ns += BILLION; > + } > + > + r.tv_sec = s; > + r.tv_nsec = ns; > + } > + > + return r; > +}