Re: CGFloat and 64 Bit
Re: CGFloat and 64 Bit
- Subject: Re: CGFloat and 64 Bit
- From: Michael Ash <email@hidden>
- Date: Mon, 9 Feb 2009 23:29:02 -0500
On Mon, Feb 9, 2009 at 8:55 PM, Nick Zitzmann <email@hidden> wrote:
>
> On Feb 9, 2009, at 6:30 PM, Michael Ash wrote:
>
>> Not really sure what you mean by this. It's true that a constant such
>> as 11.2f is a less precise representation of 11.2 than the non-float
>> version. But aside from actually defining the constants (and note that
>> all exact integers under 2^23 and many common fractional values will
>> be *exactly* represented and thus suffer no precision loss) there's no
>> trouble to be had.
>
>
> Actually, there is trouble, for small values of "trouble". Try running this
> code in GDB:
>
> int main(int argc, char **argv)
> {
> double bigDouble =
> 20.0356412345678901234567890123456789012345678901234567890;
> double test1 = bigDouble / 2.345678;
> double test2 = bigDouble / 2.345678f;
> double test3 = bigDouble / 2.345678;
>
> return 0;
> }
>
> When I try this, test1 comes out to about 8.5415138968638882, whereas test2
> comes out to 8.541513565318839. And just to eliminate one other possibility,
> test3 is identical to test1. Apparently test2 lost precision by being
> divided by a float constant. I've been unable to Google why this is
> happening, so I can only guess that either GCC is downscan-converting the
> results of the division by the float constant, or GDB is playing games with
> me.
No, that's not it at all. What's happening is that 2.345678 can't be
precisely represented as a floating-point number. You get an
imprecise, rounded representation, much like you would get if you
tried to represent 1/3 in a finite number of decimal digits. And since
float and double have different levels of precision, it happens that
2.345678 does NOT equal 2.345678f. It's not just a difference in type,
it's a difference in *value*:
printf("%.20f\n", 2.345678f - 2.345678);
Produces:
0.00000009104919440617
You're doing your tests on different numbers. Of *course* the answer
isn't the same.
If you print out the constants, you'll discover that the float
constant is actually equal to 2.34567809104919433594. (And the double
constant is equal to 2.34567799999999992977. And note that even these
are imprecise representations of their true values, but with enough
digits to reproduce them with full accuracy.) If you use
2.34567809104919433594 and 2.34567809104919433594f in your test
program you will find that you get the exact same answer in both
places.
As I said above, no precision gets lost simply because you include a
float in the calculation. What happens is that the float itself is not
always as precise as you'd like it to be. But that is not a problem if
your float is an exactly-representable number, such as any integer
under 16 million or so, or if you're doing something that doesn't care
about six decimal places of accuracy, like graphics.
> I discovered this a while back while working on a brand new 32/64-bit hybrid
> project that did a lot of floating point math, that I ended up scrapping.
> Originally I did all the math using float constants, then abandoned that for
> double constants and -fsingle-precision-constant when I realized some
> precision was being lost...
I must confess that I can't understand your reasoning here. Nothing
prevents you from using doubles everywhere in a 32-bit program. If
precision is your goal, surely that would be the correct course of
action. Furthermore, using -fsingle-precision-constant when your goal
is to have *more* precision is completely backwards. All that does is
ensure that every floating-point constant in your program is equally
bad.
In any case it's all pretty well irrelevant to the question at hand,
which is what to do about constants being used for Cocoa graphics. In
that case, an imprecision of a few parts per million is not going to
make the slightest bit of difference.
Mike
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden