Casting double to ulong weirdness

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Mon Aug 24 10:26:11 PDT 2015


On 8/24/15 12:52 PM, "=?UTF-8?B?Ik3DoXJjaW8=?= Martins\" 
<marcioapm at gmail.com>\"" wrote:
> I'm posting this here for visibility. This was silently corrupting our
> data, and might be doing the same for others as well.
>
> import std.stdio;
> void main() {
>    double x = 1.2;
>    writeln(cast(ulong)(x * 10.0));
>    double y = 1.2 * 10.0;
>    writeln(cast(ulong)y);
> }
>
> Output:
> 11
> 12

Yes. This is part of the issue of floating point. 1.2 cannot be 
represented accurately.

The second case is done via real, not double, and at compile time (i.e. 
constant folding). There may be other reasons why this works.

You are better off adding a small epsilon:

writeln(cast(ulong)(x * 10.0 + 0.1));

> to!ulong instead of the cast does the right thing, and is a viable
> work-around.

to!ulong likely adds the epsilon, but you'd have to look to be sure.

Note, this is NOT a D problem, this is a problem with floating point. 
And by problem, I mean feature-that-you-should-avoid :)

-Steve


More information about the Digitalmars-d mailing list