Casting double to ulong weirdness

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Tue Aug 25 07:54:41 PDT 2015


On 8/25/15 9:51 AM, "=?UTF-8?B?Ik3DoXJjaW8=?= Martins\" 
<marcioapm at gmail.com>\"" wrote:
> On Tuesday, 25 August 2015 at 11:14:35 UTC, Steven Schveighoffer wrote:
>> On 8/24/15 5:34 PM, "=?UTF-8?B?Ik3DoXJjaW8=?= Martins\"
>> <marcioapm at gmail.com>\"" wrote:
>>> On Monday, 24 August 2015 at 21:03:50 UTC, Steven Schveighoffer wrote:
>>
>>>> I understand the inconsistency, and I agree it is an issue that should
>>>> be examined. But the issue is entirely avoidable by not using
>>>> incorrect methods to convert from floating point to integer after
>>>> floating point operations introduce some small level of error.
>>>>
>>>> Perhaps there is some way to make it properly round in this case, but
>>>> I guarantee it will not fix all floating point errors.
>>>>
>>>
>>> What is the correct way to truncate, not round, a floating-point value
>>> to an integer?
>>
>> auto result = cast(ulong)(x * 10.0 + x.epsilon);
>>
>
> import std.stdio;
> void main() {
>      double x = 1.2;
>      writeln(cast(ulong)(x * 10.0 + x.epsilon));

Sorry, I misunderstood what epsilon was (I think it's the smallest 
incremental value for a given floating point type with an exponent of 
1). Because your number is further away than this value, it doesn't help.

You need to add something to correct for the error that might exist. The 
best thing to do is to add a very small number, as that will only adjust 
truly close numbers.

In this case, the number you could add is 0.1, since it's not going to 
affect anything other than a slightly-off value. It depends on where you 
expect the error to be.

As bachmeier says, it's not something that's easy to get right.

>
>      double y = x * 10.0;
>      writeln(cast(ulong)(y + x.epsilon));
>
>      double z = x * 10.0 + x.epsilon;
>      writeln(cast(ulong)(z));

these work because you have converted to double, which appears to round up.

-Steve


More information about the Digitalmars-d mailing list