Casting double to ulong weirdness

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Mon Aug 24 12:23:43 PDT 2015


On 8/24/15 1:43 PM, bachmeier wrote:
> On Monday, 24 August 2015 at 16:52:54 UTC, Márcio Martins 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
>>
>>
>> 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)
>
> I would not describe to!ulong as a "work-around". You just discovered
> one of the reasons to! exists: it is the right way to do it and
> cast(ulong) is the wrong way. As the others have noted, floating point
> is tricky business, and you need to use the right tools for the job.

real y = x * 10.0;
writeln(y.to!ulong); // 11

to! does not do anything different than cast. What is happening here is 
the implicit cast from real to double. D treats the result of x * 10.0 
as type double, but it's done at real precision. In that conversion, the 
error is hidden by a rounding automatically done by the processor I think.

-Steve


More information about the Digitalmars-d mailing list