mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-30 00:11:26 +00:00
dd option of doing fuzzy equality tests.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@27958 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
1db6e01877
commit
1be05b5cd7
3 changed files with 123 additions and 29 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
2009-02-23 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Headers/Foundation/NSGeometry.h:
|
||||
* Source/NSGeometry.m:
|
||||
Inspired by Matt Rice's comments on NSEqualRects(), moved the
|
||||
equality testing functions from the header to the implementation
|
||||
file and added conditionally compiled code to allow us to do a
|
||||
fuzzy equality test. Still need to decide whether this is actually
|
||||
the correct thing to do though.
|
||||
|
||||
2009-02-22 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/NSUnarchiver.m:
|
||||
|
|
|
@ -423,41 +423,18 @@ NSIntersectionRect (NSRect aRect, NSRect bRect)
|
|||
|
||||
/** Test geometric relationships... **/
|
||||
|
||||
GS_GEOM_SCOPE BOOL
|
||||
/** Returns 'YES' iff aRect's and bRect's origin and size are the same. */
|
||||
GS_EXPORT BOOL
|
||||
NSEqualRects(NSRect aRect, NSRect bRect) GS_GEOM_ATTR;
|
||||
|
||||
/** Returns 'YES' iff aRect's and bRect's origin and size are the same. */
|
||||
GS_GEOM_SCOPE BOOL
|
||||
NSEqualRects(NSRect aRect, NSRect bRect)
|
||||
{
|
||||
return ((NSMinX(aRect) == NSMinX(bRect))
|
||||
&& (NSMinY(aRect) == NSMinY(bRect))
|
||||
&& (NSWidth(aRect) == NSWidth(bRect))
|
||||
&& (NSHeight(aRect) == NSHeight(bRect))) ? YES : NO;
|
||||
}
|
||||
|
||||
GS_GEOM_SCOPE BOOL
|
||||
NSEqualSizes(NSSize aSize, NSSize bSize) GS_GEOM_ATTR;
|
||||
|
||||
/** Returns 'YES' iff aSize's and bSize's width and height are the same. */
|
||||
GS_GEOM_SCOPE BOOL
|
||||
NSEqualSizes(NSSize aSize, NSSize bSize)
|
||||
{
|
||||
return ((aSize.width == bSize.width)
|
||||
&& (aSize.height == bSize.height)) ? YES : NO;
|
||||
}
|
||||
|
||||
GS_GEOM_SCOPE BOOL
|
||||
NSEqualPoints(NSPoint aPoint, NSPoint bPoint) GS_GEOM_ATTR;
|
||||
GS_EXPORT BOOL
|
||||
NSEqualSizes(NSSize aSize, NSSize bSize) GS_GEOM_ATTR;
|
||||
|
||||
/** Returns 'YES' iff aPoint's and bPoint's x- and y-coordinates
|
||||
* are the same. */
|
||||
GS_GEOM_SCOPE BOOL
|
||||
NSEqualPoints(NSPoint aPoint, NSPoint bPoint)
|
||||
{
|
||||
return ((aPoint.x == bPoint.x)
|
||||
&& (aPoint.y == bPoint.y)) ? YES : NO;
|
||||
}
|
||||
GS_EXPORT BOOL
|
||||
NSEqualPoints(NSPoint aPoint, NSPoint bPoint) GS_GEOM_ATTR;
|
||||
|
||||
GS_GEOM_SCOPE BOOL
|
||||
NSMouseInRect(NSPoint aPoint, NSRect aRect, BOOL flipped) GS_GEOM_ATTR;
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include "config.h"
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include "GNUstepBase/preface.h"
|
||||
#include "Foundation/NSString.h"
|
||||
#include "Foundation/NSGeometry.h"
|
||||
|
@ -388,3 +389,109 @@ NSRectFromString(NSString* string)
|
|||
}
|
||||
}
|
||||
|
||||
/* Tests for equality of floats/doubles.
|
||||
* WARNING assumes the values are in the standard IEEE format ...
|
||||
* this may not be true on all systems, though afaik it is the case
|
||||
* on all systems we target.
|
||||
*
|
||||
* We use integer arithmetic for speed, assigning the float/double
|
||||
* to an integer of the same size and then converting any negative
|
||||
* values to twos-complement integer values so that a simple integer
|
||||
* comparison can be done.
|
||||
*
|
||||
* MAX_ULP specified the number of Units in the Last Place by which
|
||||
* the two values may differ and still be considered equal. A value
|
||||
* of zero means that the two numbers must be identical.
|
||||
*
|
||||
* The way that infinity is represented means that it will be considered
|
||||
* equal to MAX_FLT (or MAX_DBL) unless we are doing an exact comparison
|
||||
* with MAX_ULP set to zero.
|
||||
*
|
||||
* The implementation will also treat two NaN values as being equal, which
|
||||
* is technically wrong ... but is it worth adding a check for that?
|
||||
*/
|
||||
#define MAX_ULP 0
|
||||
static inline BOOL
|
||||
almostEqual(CGFloat A, CGFloat B)
|
||||
{
|
||||
#if MAX_ULP == 0
|
||||
return (A == B) ? YES : NO;
|
||||
#else /* MAX_UPL == 0 */
|
||||
#if defined(CGFLOAT_IS_DBL)
|
||||
union {int64_t i; double d;} valA, valB;
|
||||
|
||||
valA.d = A;
|
||||
valB.d = B;
|
||||
#if GS_SIZEOF_LONG == 8
|
||||
if (valA.i < 0)
|
||||
{
|
||||
valA.i = 0x8000000000000000L - valA.i;
|
||||
}
|
||||
if (valB.i < 0)
|
||||
{
|
||||
valB.i = 0x8000000000000000L - valB.i;
|
||||
}
|
||||
if (labs(valA.i - valB.i) <= MAX_ULP)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
#else /* GS_SIZEOF_LONG == 8 */
|
||||
if (valA.i < 0)
|
||||
{
|
||||
valA.i = 0x8000000000000000LL - valA.i;
|
||||
}
|
||||
if (valB.i < 0)
|
||||
{
|
||||
valB.i = 0x8000000000000000LL - valB.i;
|
||||
}
|
||||
if (llabs(valA.i - valB.i) <= MAX_ULP)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
#endif /* GS_SIZEOF_LONG == 8 */
|
||||
return NO;
|
||||
#else /* DEFINED(CGFLOAT_IS_DBL) */
|
||||
union {int32_t i; float f;} valA, valB;
|
||||
|
||||
valA.f = A;
|
||||
if (valA.i < 0)
|
||||
{
|
||||
valA.i = 0x80000000 - valA.i;
|
||||
}
|
||||
valB.f = B;
|
||||
if (valB.i < 0)
|
||||
{
|
||||
valB.i = 0x80000000 - valB.i;
|
||||
}
|
||||
if (abs(valA.i - valB.i) <= MAX_ULP)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
#endif /* DEFINED(CGFLOAT_IS_DBL) */
|
||||
#endif /* MAX_UPL == 0 */
|
||||
}
|
||||
|
||||
BOOL
|
||||
NSEqualRects(NSRect aRect, NSRect bRect)
|
||||
{
|
||||
return (almostEqual(NSMinX(aRect), NSMinX(bRect))
|
||||
&& almostEqual(NSMinY(aRect), NSMinY(bRect))
|
||||
&& almostEqual(NSWidth(aRect), NSWidth(bRect))
|
||||
&& almostEqual(NSHeight(aRect), NSHeight(bRect))) ? YES : NO;
|
||||
}
|
||||
|
||||
BOOL
|
||||
NSEqualSizes(NSSize aSize, NSSize bSize)
|
||||
{
|
||||
return (almostEqual(aSize.width, bSize.width)
|
||||
&& almostEqual(aSize.height, bSize.height)) ? YES : NO;
|
||||
}
|
||||
|
||||
BOOL
|
||||
NSEqualPoints(NSPoint aPoint, NSPoint bPoint)
|
||||
{
|
||||
return (almostEqual(aPoint.x, bPoint.x)
|
||||
&& almostEqual(aPoint.y, bPoint.y)) ? YES : NO;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue