Best way to compare CGFloats

2010-06-30 Thread Rimas M.
Hello,

I am stuck with floats (doubles, to be precise) comparison.
In part of my app, I am dealing with NSPoint components (x, y)
comparison. On 32bit architecture NSPoint components are floats, and
direct comparison ( float1 == float2 ) works fine. But on 64bit, they
are doubles and '==' does not work due to precision.

Lets take an example: C and D are NSPoints. Lets say C is
(1.000444089209850063, whatever) and D is
(1.00, whatever).
If my code is: if (C.x == D.x) thenDoSomething; , then thenDoSomething
is not called. Of course.

But on my needs, float is more than enough for precision.

So question is, what is the most efficient (performance side) and
simplest (coding side) way to compare those bastards?

At the moment I am thinking about:

a) BOOL _floatsOrDoublesAreEqual = ( (float)C.x == (float)D.x);

b) BOOL _floatsOrDoublesAreEqual = ( fabs(C.x - D.x) = _epsilon ); ,
where _epsilon is something like 0.0001.

Regards,

Rimas M.
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Best way to compare CGFloats

2010-06-30 Thread Roland King
I usually use fabs() and compare to some small number for things like this, it 
explicitly says what your tolerance for 'same' is and if your points are going 
through a series of calculations, it's easy to get them to differ in the lower 
order bits however you cast them. 


On 30-Jun-2010, at 4:35 PM, Rimas M. wrote:

 Hello,
 
 I am stuck with floats (doubles, to be precise) comparison.
 In part of my app, I am dealing with NSPoint components (x, y)
 comparison. On 32bit architecture NSPoint components are floats, and
 direct comparison ( float1 == float2 ) works fine. But on 64bit, they
 are doubles and '==' does not work due to precision.
 
 Lets take an example: C and D are NSPoints. Lets say C is
 (1.000444089209850063, whatever) and D is
 (1.00, whatever).
 If my code is: if (C.x == D.x) thenDoSomething; , then thenDoSomething
 is not called. Of course.
 
 But on my needs, float is more than enough for precision.
 
 So question is, what is the most efficient (performance side) and
 simplest (coding side) way to compare those bastards?
 
 At the moment I am thinking about:
 
 a) BOOL _floatsOrDoublesAreEqual = ( (float)C.x == (float)D.x);
 
 b) BOOL _floatsOrDoublesAreEqual = ( fabs(C.x - D.x) = _epsilon ); ,
 where _epsilon is something like 0.0001.
 
 Regards,
 
 Rimas M.
 ___
 
 Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
 
 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:
 http://lists.apple.com/mailman/options/cocoa-dev/rols%40rols.org
 
 This email sent to r...@rols.org

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Best way to compare CGFloats

2010-06-30 Thread Jean-Daniel Dupas

Le 30 juin 2010 à 10:35, Rimas M. a écrit :

 Hello,
 
 I am stuck with floats (doubles, to be precise) comparison.
 In part of my app, I am dealing with NSPoint components (x, y)
 comparison. On 32bit architecture NSPoint components are floats, and
 direct comparison ( float1 == float2 ) works fine. But on 64bit, they
 are doubles and '==' does not work due to precision.
 
 Lets take an example: C and D are NSPoints. Lets say C is
 (1.000444089209850063, whatever) and D is
 (1.00, whatever).
 If my code is: if (C.x == D.x) thenDoSomething; , then thenDoSomething
 is not called. Of course.
 
 But on my needs, float is more than enough for precision.
 
 So question is, what is the most efficient (performance side) and
 simplest (coding side) way to compare those bastards?
 
 At the moment I am thinking about:
 
 a) BOOL _floatsOrDoublesAreEqual = ( (float)C.x == (float)D.x);
 
 b) BOOL _floatsOrDoublesAreEqual = ( fabs(C.x - D.x) = _epsilon ); ,
 where _epsilon is something like 0.0001.
 

You should not rely on the fact that it works with float. Comparing floating 
point value is never safe.

So, as the solution a does not solve the problem (you cannot safely compare 
floating point value), I would choose the b.


-- Jean-Daniel




___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Best way to compare CGFloats

2010-06-30 Thread Alastair Houghton
On 30 Jun 2010, at 09:35, Rimas M. wrote:

 So question is, what is the most efficient (performance side) and
 simplest (coding side) way to compare those bastards?
 
 At the moment I am thinking about:
 
 a) BOOL _floatsOrDoublesAreEqual = ( (float)C.x == (float)D.x);
 
 b) BOOL _floatsOrDoublesAreEqual = ( fabs(C.x - D.x) = _epsilon ); ,
 where _epsilon is something like 0.0001.

fabs is the right way to do this in most cases, *but* with co-ordinate values 
it may be that you are actually more interested in the distance of one point 
from the other---i.e. you might in fact be interested in

  CGFloat dx = C.x - D.x, dy = C.y - D.y;
  BOOL pointsAreEqual = (dx * dx + dy * dy)  epsilonSquared;

It rather depends on what you want, and that's going to differ from one 
application to another.

Kind regards,

Alastair.

--
http://alastairs-place.net



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Best way to compare CGFloats

2010-06-30 Thread Rimas M.
Thanks everyone for answers. Now situation is more clear.

On Wed, Jun 30, 2010 at 12:14 PM, Alastair Houghton
alast...@alastairs-place.net wrote:

 fabs is the right way to do this in most cases, *but* with co-ordinate values 
 it may be that you are actually more interested in the distance of one point 
 from the other---i.e. you might in fact be interested in

  CGFloat dx = C.x - D.x, dy = C.y - D.y;
  BOOL pointsAreEqual = (dx * dx + dy * dy)  epsilonSquared;

 It rather depends on what you want, and that's going to differ from one 
 application to another.

In my case I am interested in x's and y's comparison. Not points as
themselves. But your suggestion gave me another question, which I have
never thought about before - how NSEqualPoints, ...Rects etc works? I
guess they *must* be safe to use, because NSPoint, NSRect etc relies
on floats/doubles. Or they uses the same '==' and are TRUE only if
points/rects are *really* equal?

Best Regards,

Rimas M.
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Best way to compare CGFloats

2010-06-30 Thread Alastair Houghton
On 30 Jun 2010, at 10:46, Rimas M. wrote:

 In my case I am interested in x's and y's comparison. Not points as
 themselves. But your suggestion gave me another question, which I have
 never thought about before - how NSEqualPoints, ...Rects etc works? I
 guess they *must* be safe to use, because NSPoint, NSRect etc relies
 on floats/doubles. Or they uses the same '==' and are TRUE only if
 points/rects are *really* equal?

I think they test for exact equality.  Whether that's documented or not I'm
not certain, but disassembling those functions appears to support that
conclusion.

Kind regards,

Alastair.

--
http://alastairs-place.net



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Best way to compare CGFloats

2010-06-30 Thread Rimas M.
On Wed, Jun 30, 2010 at 1:06 PM, Alastair Houghton
alast...@alastairs-place.net wrote:
 I think they test for exact equality.  Whether that's documented or not I'm
 not certain, but disassembling those functions appears to support that
 conclusion.

I see. Hope that will not cause any unexpected problems. For now I am
going to use:

#define cDefaultFloatComparisonEpsilon  0.0001
#define cEqualFloats(f1, f2, epsilon)   ( fabs( (f1) - (f2) )  epsilon )
#define cNotEqualFloats(f1, f2, epsilon)( !cEqualFloats(f1, f2, 
epsilon) )

Thank you for your help.

Regards,

Rimas M.
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Best way to compare CGFloats (Rick B.)

2010-06-30 Thread Frederick Bartram

I am stuck with floats (doubles, to be precise) comparison.


Machine 'real-numbers' such as floats and doubles should be thought of  
as intervals or neighborhoods near the mathematical number. Tests for  
'equality' of machine reals should never use machine equality '=='  
operators. 'Equality' of two machine reals , in this case, means that  
the two numbers are separated by a distance less than some small  
number, such as '(fabs(a-b)  epsilon)'. Exactly what the value of  
epsilon should be gets a little tricky.


Hope that I am not being too pedantic but imo you should never test  
for 'equality' ('==') when using machine real data types.


Rick B.
*-
* Stop spam before it gets to your mailbox! Support blocklists.
* I use http://www.spamcop.net/.
* my PGP key id: 0x63fa758 keyserver: http://keyserver1.pgp.com
*/

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Best way to compare CGFloats (Rick B.)

2010-06-30 Thread Alastair Houghton
On 30 Jun 2010, at 15:56, Frederick Bartram wrote:

 Hope that I am not being too pedantic but imo you should never test for 
 'equality' ('==') when using machine real data types.

Sometimes you really do want binary equivalence, and in that case == may be the 
right thing to use.  Normally, though, you're quite right, you need to be 
careful with floating point comparisons (not just equality tests, actually; 
sometimes for greater-than or less-than comparisons you might want two floats 
to be un-ordered if they're close in value).

I thought it'd be useful to link to the excellent What Every Computer 
Scientist Should Know About Floating-Point Arithmetic, since that's usually 
the best thing to give to people who are worrying about this kind of thing:

http://dlc.sun.com/pdf/800-7895/800-7895.pdf
http://docs.sun.com/source/806-3568/ncg_goldberg.html

Anyone who hasn't read it should.

Kind regards,

Alastair.

-- 
http://alastairs-place.net



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Best way to compare CGFloats (Rick B.)

2010-06-30 Thread Michael Ash
On Wed, Jun 30, 2010 at 11:11 AM, Alastair Houghton
alast...@alastairs-place.net wrote:
 On 30 Jun 2010, at 15:56, Frederick Bartram wrote:

 Hope that I am not being too pedantic but imo you should never test for 
 'equality' ('==') when using machine real data types.

 Sometimes you really do want binary equivalence, and in that case == may be 
 the right thing to use.

While we're being pedantic, note that == is not always the same as
binary equivalence. For example, 0.0 == -0.0, and x != x when x =
NAN.

Using == can make sense when you know that your values are exact
integers, which is not an uncommon scenario, but neither is it the
usual one.

Mike
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Best way to compare CGFloats (Rick B.)

2010-06-30 Thread Alastair Houghton
On 30 Jun 2010, at 17:37, Michael Ash wrote:

 While we're being pedantic, note that == is not always the same as
 binary equivalence. For example, 0.0 == -0.0, and x != x when x =
 NAN.

That's a good point.  I spoke inaccurately.

 Using == can make sense when you know that your values are exact
 integers, which is not an uncommon scenario, but neither is it the
 usual one.

It may also make sense sometimes with floating point values.  An example might 
be where you have an object that you're using as the key for an NSDictionary; 
in that case, your -isEqual: method may well want to do a proper equality test.

These are, however, special situations.

Kind regards,

Alastair.

--
http://alastairs-place.net




___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com