--- 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!