On 8/24/15 2:38 PM, Steven Schveighoffer wrote:
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.
More data:
It definitely has something to do with the representation of 1.2 * 10.0
in *real*.
I changed the code so that it writes the result of the multiplication to
a shared double.
In this case it *works* and prints 12, just like C does.
This also works:
double x = 1.2;
double y = x * 10.0;
writeln(cast(ulong)y); // 12
However, change y to a real, and you get 11.
Note that if I first convert from real to double, then convert to ulong,
it works.
This code:
double x = 1.2;
double x2 = x * 10.0;
real y = x * 10.0;
real y2 = x2;
double y3 = y;
writefln("%a, %a, %a", y, y2, cast(real)y3);
outputs:
0xb.ffffffffffffep+0, 0xcp+0, 0xcp+0
So some rounding happens in the conversion from real to double, that
doesn't happen in the conversion from real to ulong.
All this gets down to: FP cannot accurately represent decimal. Should
this be fixed? Can it be fixed? I don't know. But I would be very
cautious about converting anything FP to integers without some epsilon.
-Steve