mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 00:30:53 +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>
|
2009-02-22 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
* Source/NSUnarchiver.m:
|
* Source/NSUnarchiver.m:
|
||||||
|
|
|
@ -423,41 +423,18 @@ NSIntersectionRect (NSRect aRect, NSRect bRect)
|
||||||
|
|
||||||
/** Test geometric relationships... **/
|
/** 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;
|
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. */
|
/** Returns 'YES' iff aSize's and bSize's width and height are the same. */
|
||||||
GS_GEOM_SCOPE BOOL
|
GS_EXPORT BOOL
|
||||||
NSEqualSizes(NSSize aSize, NSSize bSize)
|
NSEqualSizes(NSSize aSize, NSSize bSize) GS_GEOM_ATTR;
|
||||||
{
|
|
||||||
return ((aSize.width == bSize.width)
|
|
||||||
&& (aSize.height == bSize.height)) ? YES : NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
GS_GEOM_SCOPE BOOL
|
|
||||||
NSEqualPoints(NSPoint aPoint, NSPoint bPoint) GS_GEOM_ATTR;
|
|
||||||
|
|
||||||
/** Returns 'YES' iff aPoint's and bPoint's x- and y-coordinates
|
/** Returns 'YES' iff aPoint's and bPoint's x- and y-coordinates
|
||||||
* are the same. */
|
* are the same. */
|
||||||
GS_GEOM_SCOPE BOOL
|
GS_EXPORT BOOL
|
||||||
NSEqualPoints(NSPoint aPoint, NSPoint bPoint)
|
NSEqualPoints(NSPoint aPoint, NSPoint bPoint) GS_GEOM_ATTR;
|
||||||
{
|
|
||||||
return ((aPoint.x == bPoint.x)
|
|
||||||
&& (aPoint.y == bPoint.y)) ? YES : NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
GS_GEOM_SCOPE BOOL
|
GS_GEOM_SCOPE BOOL
|
||||||
NSMouseInRect(NSPoint aPoint, NSRect aRect, BOOL flipped) GS_GEOM_ATTR;
|
NSMouseInRect(NSPoint aPoint, NSRect aRect, BOOL flipped) GS_GEOM_ATTR;
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include "GNUstepBase/preface.h"
|
#include "GNUstepBase/preface.h"
|
||||||
#include "Foundation/NSString.h"
|
#include "Foundation/NSString.h"
|
||||||
#include "Foundation/NSGeometry.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