cast(int) getting an unexpected number
Lars T. Kyllingstad
public at kyllingen.NOSPAMnet
Wed Nov 4 10:11:39 PST 2009
Charles Hixson wrote:
> Lars T. Kyllingstad wrote:
>> Michal Minich wrote:
>>> Hello rmcguire,
>>>
>>>> why is this not a compiler bug?
>>>> because:
>>>> import std.stdio;
>>>> void main() {
>>>> float f=0.01;
>>>> writefln("%0.2f->%d",f,cast(int)(f*100f));
>>>> writefln("%0.2f->%d",f,cast(int)(.01*100f));
>>>> writefln("%0.2f->%f",f,(f*100f));
>>>> }
>>>> results in:
>>>> 0.01->0
>>>> 0.01->1
>>>> 0.01->1.000000
>>>> I would say something is dodgy.
>>>>
>>>> -Rory
>>>>
>>>
>>> I think this may be case of:
>>> At comple time floating point computations may be done at a higher
>>> precision than run time.
>>
>>
>> Yes, if you do this:
>>
>> float f = 0.01;
>> float g = f * 100f;
>> real r = f * 100f;
>> writeln("%s, %s, %s", f, cast(int) g, cast(int) r);
>>
>> you get:
>>
>> 0.01, 0, 1
>>
>> I believe just writing cast(int)(f*100f) is more or less the same as the
>> 'real' case above.
>>
>> -Lars
> Can that *really* be the explanation?? I know that float doesn't have
> all that much precision, but I thought it was more than 5 or 6
> places...and this is, essentially, two places.
Yes it does, but that's not what matters.
Say that for floats, the representable number closest to 0.01 is
0.01000000000001. (This is just an example, I don't know the true
number.) Then you have a lot more precision than the two digits you
mention, and multiplying with 100 gives 1.000000000001. Round this
towards zero (which is what cast(int) does) and you get 1. This is the
'float g = f*100f;' case in my example.
Now, say that for reals, which (I think) is what the compiler uses
internally, the number closest to 0.01 is
0.0099999999999999999999999999999999999999.
Again, just an example, the point is that the precision is higher than
the above, but the closest number is now smaller than 0.01. Multiply
this by 100, and you get
0.99999999999999999999999999999999999999.
This number will be cast to the integer 0, which happens in the OP's case.
I admit I'm no expert in these things, but I suspect this is how it
goes. By the way, I recommend Don's excellent article on floating-point
numbers. It has really cleared things up for me:
http://www.digitalmars.com/d/2.0/d-floating-point.html
-Lars
More information about the Digitalmars-d-learn
mailing list