Float.st
changeset 22559 ff1a09a98286
parent 22491 e3e465028518
child 22560 929729f056e7
--- 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
     "
 !