#BUGFIX by stefan
class: ShortFloat
changed: #isAlmostEqualTo:nEpsilon:
class: ShortFloat class
comment/format in: #epsilon
fix for {Long,Short}Float>>#isAlmostEqualTo:nEpsilon: for values near 0
--- a/ShortFloat.st Thu May 10 01:22:36 2018 +0200
+++ b/ShortFloat.st Thu May 10 01:23:17 2018 +0200
@@ -343,20 +343,15 @@
(i.e. the value-delta of the least significant bit)"
Epsilon isNil ifTrue:[
- Epsilon := self computeEpsilon.
+ Epsilon := self computeEpsilon.
].
^ Epsilon
- "
- Float epsilon -> 2.22044604925031E-16
- ShortFloat epsilon -> 1.19209289550781E-07
- LongFloat epsilon -> 1.0842021724855E-19
- QDouble epsilon -> 1.21543267145725E-63
- "
-
"Modified (comment): / 21-06-2017 / 13:56:47 / cg"
+ "Modified (comment): / 10-05-2018 / 01:09:13 / stefan"
! !
+
!ShortFloat class methodsFor:'binary storage'!
readBinaryIEEESingleFrom:aStream
@@ -588,6 +583,7 @@
"Modified: 23.4.1996 / 09:26:45 / cg"
! !
+
!ShortFloat class methodsFor:'queries'!
defaultPrintPrecision
@@ -1133,7 +1129,7 @@
"
Epsilon isNil ifTrue:[
- Epsilon := self class computeEpsilon.
+ Epsilon := self class computeEpsilon.
].
%{ /* NOCONTEXT */
@@ -1150,42 +1146,45 @@
INT32 ulpDiff;
union {
- float f;
- INT32 i;
+ float f;
+ INT32 i;
} myself, otherFloat;
int nEpsilon;
float scaledEpsilon;
if (!__isSmallInteger(nE)) {
- goto tryHarder;
+ goto tryHarder;
}
nEpsilon = __intVal(nE);
scaledEpsilon = nEpsilon *__shortFloatVal(@global(Epsilon));
if (__isSmallInteger(aNumber)) {
- otherFloat.f = (float)(__intVal(aNumber));
+ otherFloat.f = (float)(__intVal(aNumber));
} else if (aNumber == nil) {
- RETURN(false)
+ RETURN(false)
} else if (__qIsFloatLike(aNumber)) {
- otherFloat.f = (float)(__floatVal(aNumber));
+ otherFloat.f = (float)(__floatVal(aNumber));
} else if (__qIsShortFloat(aNumber)) {
- otherFloat.f = (double)(__shortFloatVal(aNumber));
+ otherFloat.f = __shortFloatVal(aNumber);
+// } else if (__qIsLongFloat(aNumber)) {
+// otherFloat.f = (float)(__longFloatVal(aNumber));
} else {
- goto tryHarder;
+ goto tryHarder;
}
myself.f = __shortFloatVal(self);
// Check if the numbers are really close -- needed
// when comparing numbers near zero (ULP method below fails for numbers near 0!).
- if (fabs(myself.f - otherFloat.f) <= scaledEpsilon) {
- RETURN(true);
+ // fprintf(stderr, "%.10f %.10f\n", fabsf(myself.f - otherFloat.f), scaledEpsilon);
+ if (fabsf(myself.f - otherFloat.f) <= scaledEpsilon) {
+ RETURN(true);
}
// if the signs differ, the numbers are different
if ((myself.f >= 0) != (otherFloat.f >= 0)) {
- RETURN(false);
+ RETURN(false);
}
// compute the difference of the 'units in the last place" ULP
@@ -1193,9 +1192,9 @@
ulpDiff = myself.i - otherFloat.i;
if (ulpDiff < 0) ulpDiff = -ulpDiff;
if (ulpDiff <= nEpsilon) {
- RETURN(true);
+ RETURN(true);
} else {
- RETURN(false)
+ RETURN(false)
}
tryHarder:;
@@ -1203,11 +1202,17 @@
^ aNumber isAlmostEqualToFromShortFloat:self nEpsilon:nE
"
- 67329.234 asShortFloat isAlmostEqualTo:67329.23400000001 nEpsilon:1
- 1.0 asShortFloat isAlmostEqualTo:1.0001 nEpsilon:1
- 1.0 asShortFloat isAlmostEqualTo:-1.0 nEpsilon:1
- 1.0 asShortFloat isAlmostEqualTo:1 nEpsilon:1
+ 67329.234 asShortFloat isAlmostEqualTo:67329.23401 asShortFloat nEpsilon:1
+ 1.0 asShortFloat isAlmostEqualTo:1.0000001 asShortFloat nEpsilon:1
+ 1.0 asShortFloat isAlmostEqualTo:1.0000001 nEpsilon:1
+ 1.0 asShortFloat isAlmostEqualTo:-1.0 nEpsilon:1
+ 1.0 asShortFloat isAlmostEqualTo:1 nEpsilon:1
+ 0.0 asShortFloat isAlmostEqualTo:0 nEpsilon:1
+ 0.0 asShortFloat isAlmostEqualTo:self epsilon nEpsilon:1
+ 0.0 asShortFloat - 1.192093e-07 asShortFloat
"
+
+ "Modified: / 10-05-2018 / 00:47:22 / stefan"
!
~= aNumber