[m-rev.] time additions (was Re: for review: Add random.init/3)
Sebastian Godelet
sebastian.godelet at outlook.com
Thu May 26 13:40:27 AEST 2016
Hi,
> -----Original Message-----
> From: reviews [mailto:reviews-bounces at lists.mercurylang.org] On Behalf Of
> Peter Wang
> Sent: Thursday, May 26, 2016 11:06
> To: Julien Fischer <jfischer at opturion.com>
> Cc: Mercury Reviews <reviews at lists.mercurylang.org>
> Subject: Re: [m-rev.] time additions (was Re: for review: Add random.init/3)
>
> On Thu, 26 May 2016 12:15:52 +1000 (AEST), Julien Fischer
> <jfischer at opturion.com> wrote:
> >
> > On Thu, 26 May 2016, Paul Bone wrote:
> >
> > > 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:
> > >>
> > >> 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.
> >
> > I think we should define Mercury's float type to always be a double
> > precision type and just do away with the spf grade component entirely.
> > That would deal with the "most cases" issue above.
>
> Fine by me.
>
> > > Eww,
> > >
> > > My reaction to the use of floats for this kind of thing is rater visceral.
>
> I understand, but doubles can represent values to 2^53 precisely.
Note that .NET and Delphi's System.DateTime record are also using double precision floating point numbers to represent time,
I also don't see anything wrong with this. As long as the precision is the same for every platform.
I wish that Mercury would expose true 32-bit and 64-bit integers (from C99 for example) and double and single precision floating point number types, at least expose it to the C foreign interface.
The former would make the hash calculation functions platform independent for one thing.
>
> % date -d @$(( 2**53 ))
> Mon Nov 12 18:36:32 AEDT 285428751
>
> That ought to be enough for anybody...
>
> > > 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.
>
> Yes.
>
> > 4. Seed the PRNG using something other than time, for example:
> >
> > :- pred generate_random_int(int::out, io::di, io::uo) is det.
> >
> > and generate the int using /dev/random (on Unix) or CryptGenRandom (on
> > Windows), or whatever the appropriate OS / platform specific source of
> > randomness is. (Most OSs -- and certainly the ones that Mercury
> > actually runs on -- will provide something along those lines.)
>
> That would be useful, too.
A cryptographically secure random number generator would be really useful.
I would prefer a more fine-grained interface though,
acquire_random_source(source::uo, io::di, io::uo) is det.
Windows: CryptAcquireContext(*Source, nil, MS_ENHANCED_PROV,
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
POSIX: Source = fopen("/dev/urandom", "r");
generate_random_int(source::in?, int::out, io::di, io::uo) is det.
release_random_source(source::uo, io::di, io::uo) is det.
Windows: CryptReleaseContext(Source, 0);
POSIX: fclose(Source);
Not sure about the IO threading though
Sebastian.
More information about the reviews
mailing list