Casting double to ulong weirdness
via Digitalmars-d
digitalmars-d at puremagic.com
Mon Aug 24 10:47:56 PDT 2015
On Monday, 24 August 2015 at 17:26:12 UTC, Steven Schveighoffer
wrote:
> 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
I am familiar with floating-point representations and their
pitfalls, and I think that is not the issue here.
The issue I am trying to illustrate is the fact that the same
exact operation returns different results.
Both operations are x * 10.0, except one of them passes through
the stack before the cast.
I would expect this to be consistent, as I believe is the case in
C/C++.
More information about the Digitalmars-d
mailing list