Casting double to ulong weirdness

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


On 8/24/15 2:06 PM, rumbu wrote:
> BTW, 1.2 and 12.0 are directly representable as double
>
> In C++:
>
> printf("%.20f\r\n", 1.2);
> printf("%.20f\r\n", 12.0);
>
> will output:
>
> 1.20000000000000000000
> 12.00000000000000000000
>
> Either upcasting to real is the wrong decision here, either the writeln
> string conversion is wrong.

I don't think they are directly representable as floating point, because 
they are have factors other than 2 in the decimal portion. From my 
understanding, anything that only has to do with powers of 2 are 
representable in floating point, just like you cannot represent 1/3 in 
decimal exactly.

But there is definitely something weird going on with the casting.

I wrote this program:

testfp.d:
extern(C) void foo(double x);
void main() {
     double x = 1.2;
     foo(x);
}

testfp2.d:
extern(C) void foo(double x)
{
     import std.stdio;
     writeln(cast(ulong)(x * 10.0));
}

testfp2.c:
#include <stdio.h>

void foo(double x)
{
     printf("%lld\n", (unsigned long long)(x * 10));
}


If I link testfp.d against testfp2.c, then it outputs 12. If I link 
against testfp2.d, it outputs 11.

I have faith that printf and writeln properly output ulongs. Something 
different happens with the cast. There can be no constant folding 
operations or optimizations going on here, as this is done via separate 
compilation. I'll re-open the bug report.

-Steve


More information about the Digitalmars-d mailing list