https://issues.dlang.org/show_bug.cgi?id=6725

--- Comment #37 from Steven Schveighoffer <schvei...@yahoo.com> ---
(In reply to Jonathan M Davis from comment #31)
> Okay. I was going to say that allowing stuff like seconds(.033) would
> encourage a lack of precision even in cases where precision was required,
> and I really didn't lie that idea, but it looks like the lack of precision
> really isn't all that bad. The largest that the error gets is one hnsec:
> 
> import std.algorithm;
> import std.datetime;
> import std.stdio;
> import std.string;
> 
> void main()
> {
>     long i = 0;
>     immutable units = convert!("seconds", "hnsecs")(1);
>     immutable mult = 1.0 / units;
>     for(double d = 0; d < 1; d += mult, ++i)
>     {
>         auto result = cast(long)(d * units);
>         assert(result == i || result == i - 1 || result == i + 1,
>                format("%s %s %s", i, d, result));
>     }
> }

This is not a very good test, because mult as you defined it cannot be
represented exactly in floating point. This means you are multiplying the error
by quite a bit. A literal or parsed floating point value will not be so prone
to error.

(In reply to Walter Bright from comment #35)
> (In reply to Vladimir Panteleev from comment #34)
> > 200ms and 0.2s are the same thing,
> > how can it be meaningful to sleep for 200ms but not for 0.2s?
> 
> 0.2 cannot be represented exactly as a floating point value. Therefore,
> rounding error starts creeping in if you start adding many 0.2 increments.
> At the end, the books don't balance.

This is if you do all your time calculations in FP. This doesn't make any
sense, use Duration for your math.

In other words:

durFromInterval(someFPValue) * 100000 => no error, if we convert the FP value
properly.
durFromInterval(someFPValue * 100000) => Perhaps some error, but less stable
than the above.

> Roundoff errors must be handled by the user, not the core library, because
> the core library cannot know what the user is doing with their FP
> calculations.

I disagree, we can add a small epsilon when converting. We know more than the
user what the epsilon should be, since we define the discrete step (hnsec).

Note, the user can ALREADY do this:

dur!"nsecs"(cast(long)(someFPValue * 1_000_000_000));

We can't stop them from using FP.

But let's not discount that this ISN'T the normal way to create a duration,
it's a secondary option. And I'd much rather us define a mechanism to convert
FP to duration than let the user deal with it.

--

Reply via email to