--- a/Float.st Tue Feb 27 14:34:49 2018 +0100
+++ b/Float.st Wed Feb 28 10:51:12 2018 +0100
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
"
COPYRIGHT (c) 1988 by Claus Gittinger
All Rights Reserved
@@ -1623,14 +1625,17 @@
as the receiver, false otherwise.
nE is the number of minimal float distances, that the numbers may differ and
- still be considered equal.
+ still be considered equal.
+ That is an integer, which counts the delta-steps in the mantissa.
+ Notice, that the absolute value of the epsilon depends on the receiver
+ (i.e. with a receiver of 10^17, a mantissa-step is much larger than with 10^-17 as receiver)
For background information why floats need this
read: http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
"
Epsilon isNil ifTrue:[
- Epsilon := self class computeEpsilon.
+ Epsilon := self class computeEpsilon.
].
%{ /* NOCONTEXT */
@@ -1647,29 +1652,29 @@
INT64 ulpDiff;
union {
- double d;
- INT64 i;
+ double d;
+ INT64 i;
} myself, otherFloat;
int nEpsilon;
double scaledEpsilon;
if (!__isSmallInteger(nE)) {
- goto tryHarder;
+ goto tryHarder;
}
nEpsilon = __intVal(nE);
scaledEpsilon = nEpsilon *__floatVal(@global(Epsilon));
if (__isSmallInteger(aNumber)) {
- otherFloat.d = (double)(__intVal(aNumber));
+ otherFloat.d = (double)(__intVal(aNumber));
} else if (aNumber == nil) {
- RETURN(false)
+ RETURN(false)
} else if (__qIsFloatLike(aNumber)) {
- otherFloat.d = (double)(__floatVal(aNumber));
+ otherFloat.d = (double)(__floatVal(aNumber));
} else if (__qIsShortFloat(aNumber)) {
- otherFloat.d = (double)(__shortFloatVal(aNumber));
+ otherFloat.d = (double)(__shortFloatVal(aNumber));
} else {
- goto tryHarder;
+ goto tryHarder;
}
myself.d = __floatVal(self);
@@ -1677,12 +1682,12 @@
// Check if the numbers are really close -- needed
// when comparing numbers near zero (ULP method below fails for numbers near 0!).
if (fabs(myself.d - otherFloat.d) <= scaledEpsilon) {
- RETURN(true);
+ RETURN(true);
}
// if the signs differ, the numbers are different
if ((myself.d >= 0) != (otherFloat.d >= 0)) {
- RETURN(false);
+ RETURN(false);
}
// compute the difference of the 'units in the last place" ULP
@@ -1690,23 +1695,26 @@
ulpDiff = myself.i - otherFloat.i;
if (ulpDiff < 0) ulpDiff = -ulpDiff;
if (ulpDiff <= nEpsilon) {
- RETURN(true);
+ RETURN(true);
} else {
- RETURN(false)
+ RETURN(false)
}
tryHarder:;
%}.
+ nE isInteger ifFalse:[
+ self error:'nEpsilon argument must be an integer'.
+ ].
^ aNumber isAlmostEqualToFromFloat:self nEpsilon:nE
"
- 67329.234 isAlmostEqualTo:67329.23400000001 nEpsilon:1
- 1.0 isAlmostEqualTo:1.0001 nEpsilon:1
- 1.0 isAlmostEqualTo:-1.0 nEpsilon:1
- 1 isAlmostEqualTo:1.000000000000001 nEpsilon:1
- 1 isAlmostEqualTo:1.000000000000001 nEpsilon:10
- 1.0 isAlmostEqualTo:1 nEpsilon:1
- 1.0 isAlmostEqualTo:1 asFraction nEpsilon:1
+ 67329.234 isAlmostEqualTo:67329.23400000001 nEpsilon:1
+ 1.0 isAlmostEqualTo:1.0001 nEpsilon:1
+ 1.0 isAlmostEqualTo:-1.0 nEpsilon:1
+ 1 isAlmostEqualTo:1.000000000000001 nEpsilon:1
+ 1 isAlmostEqualTo:1.000000000000001 nEpsilon:10
+ 1.0 isAlmostEqualTo:1 nEpsilon:1
+ 1.0 isAlmostEqualTo:1 asFraction nEpsilon:1
"
!