Casting double to ulong weirdness

anonymous via Digitalmars-d digitalmars-d at puremagic.com
Mon Aug 24 10:22:45 PDT 2015


On Monday 24 August 2015 18:52,  wrote:

> 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
> 
> 
> to!ulong instead of the cast does the right thing, and is a
> viable work-around.
> 
> Issue: https://issues.dlang.org/show_bug.cgi?id=14958)

1.2 is not representable exactly in binary. Try printing it with a lot of 
decimal places:

writefln("%.20f", x); /* prints "1.19999999999999995559" */

Multiply that by 10: ~11.999; cast to ulong: 11.

Interestingly, printing x * 10.0 that way shows exactly 12:

writefln("%.20f", x * 10.0); /* 12.00000000000000000000 */

But cast one operand to real and you're back at 11.9...:

writefln("%.20f", cast(real)x * 10.0); /* 11.99999999999999955591 */

So, apparently, real precision is used in your code. This is not unexpected; 
compilers are allowed to use higher precision than requested for floating 
point operations. I think people have argued against it in the past, but so 
far Walter has been adamant about it being the right choice.


More information about the Digitalmars-d mailing list