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. --