Float.st
changeset 3146 4e46505d1d59
parent 3139 a4c5540f924a
child 3163 212a539ee379
--- a/Float.st	Mon Jan 05 18:21:31 1998 +0100
+++ b/Float.st	Wed Jan 07 13:02:20 1998 +0100
@@ -109,7 +109,7 @@
 "
     Floats represent rational numbers with limited precision. In ST/X, Float uses
     the underlying C-compilers double implementation, therefore instances of Float
-    are usually represented by the 8-byte IEE double precision float format.
+    are usually represented by the 8-byte IEEE double precision float format.
     (but there is no guaranty).
 
     Notice, that Floats are defined as Byte-array to prevent the garbage collector
@@ -128,20 +128,20 @@
     (It does the float-check by probing a bit in the classes flag instVar).
 
     Mixed mode arithmetic:
-	float op float       -> float
-	float op fix         -> float
-	float op integer     -> float
-	float op float       -> float
+        float op float       -> float
+        float op fix         -> float
+        float op integer     -> float
+        float op float       -> float
 
     [Class Variables:]
 
     [see also:]
-	Number
-	ShortFloat Fraction FixedPoint Integer
-	FloatArray DoubleArray
+        Number
+        ShortFloat Fraction FixedPoint Integer
+        FloatArray DoubleArray
 
     [author:]
-	Claus Gittinger
+        Claus Gittinger
 "
 !
 
@@ -475,6 +475,36 @@
     __qMKFLOAT(newFloat, rslt);
     RETURN ( newFloat );
 %}
+!
+
+uncheckedDivide:aNumber
+    "return the quotient of the receiver and the argument, aNumber.
+     Do not check for divide by zero (return NaN or infinity)"
+
+%{  /* NOCONTEXT */
+
+    OBJ newFloat;
+    double result, val;
+
+    if (__isSmallInteger(aNumber)) {
+        result = __floatVal(self) / ( (double)__intVal(aNumber)) ;
+retResult:
+        __qMKFLOAT(newFloat, result);
+        RETURN ( newFloat );
+    } else if (__isFloatLike(aNumber)) {
+        val = __floatVal(aNumber);
+        result = __floatVal(self) / val;
+        goto retResult;
+    }
+%}
+.
+    ^ aNumber quotientFromFloat:self
+
+
+    "
+      0.0 uncheckedDivide:0.0
+      1.0 uncheckedDivide:0.0
+    "
 ! !
 
 !Float methodsFor:'binary storage'!
@@ -900,12 +930,12 @@
     char fmtBuffer[20];
 
     if (__isString(@global(DefaultPrintFormat))) {
-	fmt = (char *) __stringVal(@global(DefaultPrintFormat));
+        fmt = (char *) __stringVal(@global(DefaultPrintFormat));
     } else {
-	/*
-	 * in case we get called before #initialize ...
-	 */
-	fmt = ".6";
+        /*
+         * in case we get called before #initialize ...
+         */
+        fmt = ".6";
     }
 
     /*
@@ -926,17 +956,17 @@
      * (i.e. look if string contains '.' or 'e' and append '.0' if not)
      */
     for (cp = buffer; *cp; cp++) {
-	if ((*cp == '.') || (*cp == 'e')) break;
+        if ((*cp == '.') || (*cp == 'e')) break;
     }
     if (! *cp) {
-	*cp++ = '.';
-	*cp++ = '0';
-	*cp = '\0';
+        *cp++ = '.';
+        *cp++ = '0';
+        *cp = '\0';
     }
 
     s = __MKSTRING(buffer COMMA_SND);
     if (s != nil) {
-	RETURN (s);
+        RETURN (s);
     }
 %}.
     "
@@ -948,11 +978,16 @@
     "
     ^ ObjectMemory allocationFailureSignal raise.
 
-    "1.0 printString"
-    "1.234 printString"
-    "1e10 printString"
-    "1.2e3 printString"
-    "1.2e30 printString"
+    "
+        1.0 printString
+        1.234 printString
+        1e10 printString
+        1.2e3 printString
+        1.2e30 printString
+        (1.0 uncheckedDivide:0) printString
+        (0.0 uncheckedDivide:0) printString
+    "
+
 !
 
 printfPrintString:formatString
@@ -1083,23 +1118,50 @@
 
 !Float methodsFor:'testing'!
 
-isInfinite
-    "return true, if the receiver is an infinite float (Inf).
-     These are not created by ST/X float operations (they raise an exception);
-     however, inline C-code could produce them ..."
+isFinite
+    "return true, if the receiver is a finite float 
+     i.e. not NaN and not infinite."
 
 %{  /* NOCONTEXT */
 
     double dV = __floatVal(self);
 
-#ifdef isinf
+    if (finite(dV)) { RETURN (true); }
+%}.
+    ^false
+
+    "
+        1.0 isFinite
+        (0.0 uncheckedDivide: 0.0) isFinite
+        (1.0 uncheckedDivide: 0.0) isFinite
+    "
+
+!
+
+isInfinite
+    "return true, if the receiver is an infinite float (Inf).
+     These are not created by ST/X float operations (they raise an exception);
+     however, inline C-code could produce them ...
+     Redefined here for speed"
+
+%{  /* NOCONTEXT */
+
+    double dV = __floatVal(self);
+
+#if defined(isinf) || defined(LINUX)
     if (isinf(dV)) { RETURN (true); }
-#endif
-#ifdef IS_INF
-    if (IS_INF(dV)) { RETURN (true); }
+#else
+    if (!finite(dV) && !isnan(dV)) { RETURN (true); }
 #endif
 %}.
-    ^false
+    ^ false
+
+    "
+        1.0 isInfinite
+        (0.0 uncheckedDivide: 0.0) isInfinite
+        (1.0 uncheckedDivide: 0.0) isInfinite
+    "
+
 !
 
 isNaN
@@ -1111,15 +1173,16 @@
 
     double dV = (__floatVal(self));
 
+    if (isnan(dV)) { RETURN (true); }
+
+#if 0 /* Currently all our systems support isnan()
+       * If not, you have to fix librun/jinterpret.c also.
+       */
+
     /*
      * sigh - every vendor is playing its own game here ...
      * Q: what are standards worth, anyway ?
      */
-#ifdef isnan
-    if (isnan(dV)) { RETURN (true); }
-    RETURN (false);
-#endif
-
 #ifdef IS_NAN
     if (IS_NAN(dV)) { RETURN (true); }
     RETURN (false);
@@ -1169,9 +1232,15 @@
     if (NaN(dV)) { RETURN (true); }
     RETURN (false);
 #endif
+
+#endif /* 0 */
 %}.
     ^ false
 
+    "
+        1.0 isNaN
+        (0.0 uncheckedDivide: 0.0) isNaN
+    "
 
 !
 
@@ -1431,6 +1500,6 @@
 !Float class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/Float.st,v 1.68 1997-12-23 17:10:05 ca Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Float.st,v 1.69 1998-01-07 12:02:20 stefan Exp $'
 ! !
 Float initialize!