[m-rev.] time additions (was Re: for review: Add random.init/3)
Paul Bone
paul at bone.id.au
Thu May 26 11:52:04 AEST 2016
On Thu, May 26, 2016 at 11:25:16AM +1000, Peter Wang wrote:
> On Wed, 25 May 2016 16:28:32 +1000, Peter Wang <novalazy at gmail.com> wrote:
> > On Wed, 25 May 2016 15:55:50 +1000, Paul Bone <paul at bone.id.au> wrote:
> > > For review by anyone
> > >
> > > ----
> > >
> > > Add random.init/3
> > >
> > > random.init/3 makes it easier to seed the random number generator. It will
> > > calculate a seed based on the current time and, if known, the process ID.
> > > This is sufficient for simple applications but shouldn't be used for
> > > security-sensitive applications.
>
> A common way to seed the PRNG in C is
>
> srand(time(0));
>
> The time in seconds-since-the-Unix-epoch is useful for many other
> purposes, in addition to seeding any PRNG implementation.
>
> I would like to see an easy way to get an integer (simple)
> representation of Unix time, as well as a way to convert between an
> integer representation and the time_t values.
>
> The main problem is probably that a signed 32-bit int cannot represent
> Unix times past some time in 2038. Apart from 32-bit machines, this
> problem also affects C# and Java backends.
>
> difftime/2 returns a float. You can get the current unix time as a
> float with
>
> time(Now, !IO),
> Secs = difftime(Now, unix_epoch)
>
> where `unix_epoch' returns a time_t.
>
> Using floats is not very satisfying but in most cases they will be
> double precision, and capable of representing any reasonable time
> value precisely.
>
> Here are some suggested additions to time.m
>
> :- func unix_epoch = time_t.
>
> :- pred seconds_since_unix_epoch(float::out, io::di, io::uo) is det.
>
> :- func seconds_since_unix_epoch(time_t) = float.
>
> :- func from_seconds_since_unix_epoch(float) = time_t.
>
> Thoughts?
Eww,
My reaction to the use of floats for this kind of thing is rater visceral.
I agree that it may be useful to expose time in seconds since the epoch for
other reasons. And as an aside, gettimeofday() could be useful if portable
too.
I think there are a few potential solutions.
1 Use an int and hope for the best for 32-bit C / Java and C# platforms.
Maybe the world will end before 2038 and we'll also never need to store
a date then or after, or if we do, just use 64-bit C. While this isn't
a great solution I'm being partly serious, because I think it's better
than using floats. Floats *shudder*.
2 Same as #1, but we also update the Java / C# backends to use 64bit
integers. AFAIK these need to be boxed in many places anyway, so I
can't imagine this having any additional penalty.
3 Don't expose seconds since epoch, instead add a predicate to random.m
which takes a time_t and seeds the PRNG from that. We could either
abusing our knowledge of the underlying representation of time_t or
create a hidden interface in time.m to expose something to read the
seconds-since-epoch.
--
Paul Bone
More information about the reviews
mailing list