--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SFloat.st Wed Apr 17 12:30:43 1996 +0200
@@ -0,0 +1,516 @@
+"
+ COPYRIGHT (c) 1996 by Claus Gittinger
+ All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice. This software may not
+ be provided or otherwise made available to, or used by, any
+ other person. No title to or ownership of the software is
+ hereby transferred.
+"
+
+
+
+LimitedPrecisionReal variableByteSubclass:#ShortFloat
+ instanceVariableNames:''
+ classVariableNames:'LastErrorNumber'
+ poolDictionaries:''
+ category:'Magnitude-Numbers'
+!
+
+!ShortFloat class methodsFor:'documentation'!
+
+copyright
+"
+ COPYRIGHT (c) 1996 by Claus Gittinger
+ All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice. This software may not
+ be provided or otherwise made available to, or used by, any
+ other person. No title to or ownership of the software is
+ hereby transferred.
+"
+
+
+!
+
+documentation
+"
+ ShortFloats represent rational numbers with limited precision. In ST/X, Float uses
+ the underlying C-compilers double implementation, while ShortFloats are
+ mapped onto C-floats.
+ Therefore instances of Float are usually represented by the 8-byte IEE
+ double precision float format, while ShortFloats use 4byte IEE format.
+ (but there is no guaranty).
+
+ Notice, that ST/X Floats are what Doubles are in ST-80 and ShortFloats are
+ ST-80's Floats respectively.
+ This may change in one of the next versions (at least on machines, which
+ provide different float and double types in their C-compiler.
+
+ WARNING:
+ The layout of shortFloat instances is known by the runtime system and the compiler;
+ you may not add instance variables here.
+ Also, subclassing is complicated by the fact, that the VM creates floats/shortFloats,
+ and does its float-checks by an identity compare with the ShortFloat-class.
+ (i.e. your subclasses instances may not be recognized as float-like objects,
+ thus mixed mode arithmetic will always coerce them, effectively slowing things down).
+
+ This may be changed, to use a flag bit in the class.
+"
+
+! !
+
+!ShortFloat class methodsFor:'constants'!
+
+pi
+ "return the constant pi"
+
+ ^ 3.14159 asShortFloat
+
+
+!
+
+unity
+ "return the neutral element for multiplication"
+
+ ^ 1.0 asShortFloat
+
+!
+
+zero
+ "return the neutral element for addition"
+
+ ^ 0.0 asShortFloat
+
+! !
+
+!ShortFloat class methodsFor:'queries'!
+
+isBuiltInClass
+ "this class is known by the run-time-system"
+
+ ^ self == ShortFloat
+
+
+! !
+
+!ShortFloat methodsFor:'arithmetic'!
+
+* aNumber
+ "return the product of the receiver and the argument, aNumber"
+
+%{ /* NOCONTEXT */
+
+ OBJ newFloat;
+ float result;
+ double dResult;
+
+ if (__isSmallInteger(aNumber)) {
+ result = __shortFloatVal(self) * (float)(__intVal(aNumber));
+retResult:
+ __qMKSFLOAT(newFloat, result, SENDER);
+ RETURN ( newFloat );
+ }
+ if (__isShortFloat(aNumber)) {
+ result = __shortFloatVal(self) * __shortFloatVal(aNumber);
+ goto retResult;
+ }
+ if (__isFloatLike(aNumber)) {
+ dResult = (double) __shortFloatVal(self)* __floatVal(aNumber);
+ __qMKFLOAT(newFloat, dResult, SENDER);
+ RETURN ( newFloat );
+
+ }
+%}.
+ ^ aNumber productFromShortFloat:self
+!
+
++ aNumber
+ "return the sum of the receiver and the argument, aNumber"
+
+%{ /* NOCONTEXT */
+
+ OBJ newFloat;
+ float result;
+ double dResult;
+
+ if (__isSmallInteger(aNumber)) {
+ result = __shortFloatVal(self) + (float)(__intVal(aNumber));
+retResult:
+ __qMKSFLOAT(newFloat, result, SENDER);
+ RETURN ( newFloat );
+ }
+ if (__isShortFloat(aNumber)) {
+ result = __shortFloatVal(self) + __shortFloatVal(aNumber);
+ goto retResult;
+ }
+ if (__isFloatLike(aNumber)) {
+ dResult = (double) __shortFloatVal(self) + __floatVal(aNumber);
+ __qMKFLOAT(newFloat, dResult, SENDER);
+ RETURN ( newFloat );
+
+ }
+%}.
+ ^ aNumber sumFromShortFloat:self
+!
+
+- aNumber
+ "return the difference of the receiver and the argument, aNumber"
+
+%{ /* NOCONTEXT */
+
+ OBJ newFloat;
+ float result;
+ double dResult;
+
+ if (__isSmallInteger(aNumber)) {
+ result = __shortFloatVal(self) - (float)(__intVal(aNumber));
+retResult:
+ __qMKSFLOAT(newFloat, result, SENDER);
+ RETURN ( newFloat );
+ }
+ if (__isShortFloat(aNumber)) {
+ result = __shortFloatVal(self) - __shortFloatVal(aNumber);
+ goto retResult;
+ }
+ if (__isFloatLike(aNumber)) {
+ dResult = (double) __shortFloatVal(self) - __floatVal(aNumber);
+ __qMKFLOAT(newFloat, dResult, SENDER);
+ RETURN ( newFloat );
+
+ }
+%}.
+ ^ aNumber differenceFromShortFloat:self
+!
+
+/ aNumber
+ "return the quotient of the receiver and the argument, aNumber"
+
+%{ /* NOCONTEXT */
+
+ OBJ newFloat;
+ float result, val;
+ double dResult, dVal;
+
+ if (__isSmallInteger(aNumber)) {
+ if (aNumber != __MKSMALLINT(0)) {
+ result = __shortFloatVal(self) / (float)(__intVal(aNumber));
+retResult:
+ __qMKSFLOAT(newFloat, result, SENDER);
+ RETURN ( newFloat );
+ }
+ }
+ if (__isShortFloat(aNumber)) {
+ val = __shortFloatVal(aNumber);
+ if (val != 0.0) {
+ result = __shortFloatVal(self) / val;
+ goto retResult;
+ }
+ }
+ if (__isFloatLike(aNumber)) {
+ dVal = __floatVal(aNumber);
+ if (dVal != 0.0) {
+ dResult = (double) __shortFloatVal(self) / dVal;
+ __qMKFLOAT(newFloat, dResult, SENDER);
+ }
+ RETURN ( newFloat );
+
+ }
+%}.
+ ((aNumber == 0) or:[aNumber = 0.0]) ifTrue:[
+ "
+ No, you shalt not divide by zero
+ "
+ ^ DivisionByZeroSignal raise.
+ ].
+ ^ aNumber quotientFromFloat:self
+
+!
+
+negated
+ "return myself negated"
+
+%{ /* NOCONTEXT */
+ OBJ newFloat;
+ float rslt = - __shortFloatVal(self);
+
+ __qMKSFLOAT(newFloat, rslt, SENDER);
+ RETURN ( newFloat );
+%}
+
+! !
+
+!ShortFloat methodsFor:'coercion and converting'!
+
+asFloat
+ "return a Float with same value as the receiver"
+
+%{ /* NOCONTEXT */
+
+ OBJ newFloat;
+ double dVal = (double)__shortFloatVal(self);
+
+ __qMKFLOAT(newFloat, dVal, SENDER);
+ RETURN ( newFloat );
+%}
+
+ "
+ 1.0 asShortFloat
+ "
+!
+
+asInteger
+ "return an integer with same value - might truncate"
+
+%{ /* NOCONTEXT */
+
+ if ((__shortFloatVal(self) >= (float)_MIN_INT)
+ && (__shortFloatVal(self) <= (float)_MAX_INT)) {
+ RETURN ( __MKSMALLINT( (INT)__shortFloatVal(self)) );
+ }
+%}.
+ ^ super asInteger
+
+ "
+ 12345.0 asShortFloat asInteger
+ 1e15 asShortFloat asInteger
+ "
+!
+
+asShortFloat
+ "return a ShortFloat with same value as the receiver - thats me"
+
+ ^ self
+! !
+
+!ShortFloat methodsFor:'comparing'!
+
+< aNumber
+ "return true, if the argument is greater"
+
+%{ /* NOCONTEXT */
+
+ if (__isSmallInteger(aNumber)) {
+ RETURN ( (__shortFloatVal(self) < (float)(__intVal(aNumber))) ? true : false );
+ }
+ if (__isFloatLike(aNumber)) {
+ RETURN ( (double)(__shortFloatVal(self) < __floatVal(aNumber)) ? true : false );
+ }
+ if (__isShortFloat(aNumber)) {
+ RETURN ( (__shortFloatVal(self) < __shortFloatVal(aNumber)) ? true : false );
+ }
+%}.
+ ^ aNumber lessFromShortFloat:self
+
+
+!
+
+<= aNumber
+ "return true, if the argument is greater or equal"
+
+%{ /* NOCONTEXT */
+
+ if (__isSmallInteger(aNumber)) {
+ RETURN ( (__shortFloatVal(self) <= (float)(__intVal(aNumber))) ? true : false );
+ }
+ if (__isFloatLike(aNumber)) {
+ RETURN ( (double)(__shortFloatVal(self) <= __floatVal(aNumber)) ? true : false );
+ }
+ if (__isShortFloat(aNumber)) {
+ RETURN ( (__shortFloatVal(self) <= __shortFloatVal(aNumber)) ? true : false );
+ }
+%}.
+ ^ self retry:#<= coercing:aNumber
+
+!
+
+= aNumber
+ "return true, if the arguments value are equal by value"
+
+%{ /* NOCONTEXT */
+
+ if (__isSmallInteger(aNumber)) {
+ RETURN ( (__shortFloatVal(self) == (float)(__intVal(aNumber))) ? true : false );
+ }
+ if (__isFloatLike(aNumber)) {
+ RETURN ( (double)(__shortFloatVal(self) == __floatVal(aNumber)) ? true : false );
+ }
+ if (__isShortFloat(aNumber)) {
+ RETURN ( (__shortFloatVal(self) == __shortFloatVal(aNumber)) ? true : false );
+ }
+%}.
+ ^ self retry:#= coercing:aNumber
+
+!
+
+> aNumber
+ "return true, if the argument is less"
+
+%{ /* NOCONTEXT */
+
+ if (__isSmallInteger(aNumber)) {
+ RETURN ( (__shortFloatVal(self) > (float)(__intVal(aNumber))) ? true : false );
+ }
+ if (__isFloatLike(aNumber)) {
+ RETURN ( (double)(__shortFloatVal(self) > __floatVal(aNumber)) ? true : false );
+ }
+ if (__isShortFloat(aNumber)) {
+ RETURN ( (__shortFloatVal(self) > __shortFloatVal(aNumber)) ? true : false );
+ }
+%}.
+ ^ self retry:#> coercing:aNumber
+!
+
+>= aNumber
+ "return true, if the argument is less or equal"
+
+%{ /* NOCONTEXT */
+
+ if (__isSmallInteger(aNumber)) {
+ RETURN ( (__shortFloatVal(self) >= (float)(__intVal(aNumber))) ? true : false );
+ }
+ if (__isFloatLike(aNumber)) {
+ RETURN ( (double)(__shortFloatVal(self) >= __floatVal(aNumber)) ? true : false );
+ }
+ if (__isShortFloat(aNumber)) {
+ RETURN ( (__shortFloatVal(self) >= __shortFloatVal(aNumber)) ? true : false );
+ }
+%}.
+ ^ self retry:#>= coercing:aNumber
+!
+
+hash
+ "return a number for hashing; redefined, since floats compare
+ by numeric value (i.e. 3.0 = 3), therefore 3.0 hash must be the same
+ as 3 hash."
+
+ |i|
+
+ (self >= SmallInteger minVal and:[self <= SmallInteger maxVal]) ifTrue:[
+ i := self asInteger.
+ self = i ifTrue:[
+ ^ i hash
+ ].
+ ].
+
+ "
+ mhmh take some of my value-bits to hash on
+ "
+ ^ (((self basicAt:4) bitAnd:16r3F) bitShift:24) +
+ ((self basicAt:3) bitShift:16) +
+ ((self basicAt:2) bitShift:8) +
+ (self basicAt:1)
+
+ "
+ 1.2345 hash
+ 1.2345 asShortFloat hash
+ 1.0 hash
+ 1.0 asShortFloat hash
+ "
+!
+
+~= aNumber
+ "return true, if the arguments value are not equal"
+
+%{ /* NOCONTEXT */
+
+ if (__isSmallInteger(aNumber)) {
+ RETURN ( (__shortFloatVal(self) != (float)(__intVal(aNumber))) ? true : false );
+ }
+ if (__isFloatLike(aNumber)) {
+ RETURN ( (double)(__shortFloatVal(self) != __floatVal(aNumber)) ? true : false );
+ }
+ if (__isShortFloat(aNumber)) {
+ RETURN ( (__shortFloatVal(self) != __shortFloatVal(aNumber)) ? true : false );
+ }
+%}.
+ ^ self retry:#~= coercing:aNumber
+
+! !
+
+!ShortFloat methodsFor:'printing & storing'!
+
+printString
+ "return a printed representation of the receiver"
+
+%{ /* NOCONTEXT */
+
+ char buffer[64];
+ REGISTER char *cp;
+ OBJ s;
+
+ /*
+ * actually only needed on sparc: since thisContext is
+ * in a global register, which gets destroyed by printf,
+ * manually save it here - very stupid ...
+ */
+ __BEGIN_PROTECT_REGISTERS__
+
+#ifdef SYSV
+ sprintf(buffer, "%.6lg", (double)__shortFloatVal(self));
+#else
+ sprintf(buffer, "%.6G", (double)__shortFloatVal(self));
+#endif
+
+ __END_PROTECT_REGISTERS__
+
+ /*
+ * kludge to make integral float f prints as "f.0" (not as "f" as printf does)
+ * (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++ = '.';
+ *cp++ = '0';
+ *cp = '\0';
+ }
+
+ s = __MKSTRING(buffer COMMA_SND);
+ if (s != nil) {
+ RETURN (s);
+ }
+%}.
+ "
+ memory allocation (for the new string) failed.
+ When we arrive here, there was no memory, even after a garbage collect.
+ This means, that the VM wanted to get some more memory from the
+ OS, which was not kind enough to give it.
+ Bad luck - you should increase the swap space on your machine.
+ "
+ ^ ObjectMemory allocationFailureSignal raise.
+! !
+
+!ShortFloat methodsFor:'testing'!
+
+negative
+ "return true if the receiver is less than zero"
+
+%{ /* NOCONTEXT */
+
+ RETURN ( (__shortFloatVal(self) < 0.0) ? true : false );
+%}
+
+
+!
+
+positive
+ "return true if the receiver is greater or equal to zero"
+
+%{ /* NOCONTEXT */
+
+ RETURN ( (__shortFloatVal(self) >= 0.0) ? true : false );
+%}
+
+! !
+
+!ShortFloat class methodsFor:'documentation'!
+
+version
+ ^ '$Header: /cvs/stx/stx/libbasic/Attic/SFloat.st,v 1.1 1996-04-17 10:30:43 cg Exp $'
+! !
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ShortFloat.st Wed Apr 17 12:30:43 1996 +0200
@@ -0,0 +1,516 @@
+"
+ COPYRIGHT (c) 1996 by Claus Gittinger
+ All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice. This software may not
+ be provided or otherwise made available to, or used by, any
+ other person. No title to or ownership of the software is
+ hereby transferred.
+"
+
+
+
+LimitedPrecisionReal variableByteSubclass:#ShortFloat
+ instanceVariableNames:''
+ classVariableNames:'LastErrorNumber'
+ poolDictionaries:''
+ category:'Magnitude-Numbers'
+!
+
+!ShortFloat class methodsFor:'documentation'!
+
+copyright
+"
+ COPYRIGHT (c) 1996 by Claus Gittinger
+ All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice. This software may not
+ be provided or otherwise made available to, or used by, any
+ other person. No title to or ownership of the software is
+ hereby transferred.
+"
+
+
+!
+
+documentation
+"
+ ShortFloats represent rational numbers with limited precision. In ST/X, Float uses
+ the underlying C-compilers double implementation, while ShortFloats are
+ mapped onto C-floats.
+ Therefore instances of Float are usually represented by the 8-byte IEE
+ double precision float format, while ShortFloats use 4byte IEE format.
+ (but there is no guaranty).
+
+ Notice, that ST/X Floats are what Doubles are in ST-80 and ShortFloats are
+ ST-80's Floats respectively.
+ This may change in one of the next versions (at least on machines, which
+ provide different float and double types in their C-compiler.
+
+ WARNING:
+ The layout of shortFloat instances is known by the runtime system and the compiler;
+ you may not add instance variables here.
+ Also, subclassing is complicated by the fact, that the VM creates floats/shortFloats,
+ and does its float-checks by an identity compare with the ShortFloat-class.
+ (i.e. your subclasses instances may not be recognized as float-like objects,
+ thus mixed mode arithmetic will always coerce them, effectively slowing things down).
+
+ This may be changed, to use a flag bit in the class.
+"
+
+! !
+
+!ShortFloat class methodsFor:'constants'!
+
+pi
+ "return the constant pi"
+
+ ^ 3.14159 asShortFloat
+
+
+!
+
+unity
+ "return the neutral element for multiplication"
+
+ ^ 1.0 asShortFloat
+
+!
+
+zero
+ "return the neutral element for addition"
+
+ ^ 0.0 asShortFloat
+
+! !
+
+!ShortFloat class methodsFor:'queries'!
+
+isBuiltInClass
+ "this class is known by the run-time-system"
+
+ ^ self == ShortFloat
+
+
+! !
+
+!ShortFloat methodsFor:'arithmetic'!
+
+* aNumber
+ "return the product of the receiver and the argument, aNumber"
+
+%{ /* NOCONTEXT */
+
+ OBJ newFloat;
+ float result;
+ double dResult;
+
+ if (__isSmallInteger(aNumber)) {
+ result = __shortFloatVal(self) * (float)(__intVal(aNumber));
+retResult:
+ __qMKSFLOAT(newFloat, result, SENDER);
+ RETURN ( newFloat );
+ }
+ if (__isShortFloat(aNumber)) {
+ result = __shortFloatVal(self) * __shortFloatVal(aNumber);
+ goto retResult;
+ }
+ if (__isFloatLike(aNumber)) {
+ dResult = (double) __shortFloatVal(self)* __floatVal(aNumber);
+ __qMKFLOAT(newFloat, dResult, SENDER);
+ RETURN ( newFloat );
+
+ }
+%}.
+ ^ aNumber productFromShortFloat:self
+!
+
++ aNumber
+ "return the sum of the receiver and the argument, aNumber"
+
+%{ /* NOCONTEXT */
+
+ OBJ newFloat;
+ float result;
+ double dResult;
+
+ if (__isSmallInteger(aNumber)) {
+ result = __shortFloatVal(self) + (float)(__intVal(aNumber));
+retResult:
+ __qMKSFLOAT(newFloat, result, SENDER);
+ RETURN ( newFloat );
+ }
+ if (__isShortFloat(aNumber)) {
+ result = __shortFloatVal(self) + __shortFloatVal(aNumber);
+ goto retResult;
+ }
+ if (__isFloatLike(aNumber)) {
+ dResult = (double) __shortFloatVal(self) + __floatVal(aNumber);
+ __qMKFLOAT(newFloat, dResult, SENDER);
+ RETURN ( newFloat );
+
+ }
+%}.
+ ^ aNumber sumFromShortFloat:self
+!
+
+- aNumber
+ "return the difference of the receiver and the argument, aNumber"
+
+%{ /* NOCONTEXT */
+
+ OBJ newFloat;
+ float result;
+ double dResult;
+
+ if (__isSmallInteger(aNumber)) {
+ result = __shortFloatVal(self) - (float)(__intVal(aNumber));
+retResult:
+ __qMKSFLOAT(newFloat, result, SENDER);
+ RETURN ( newFloat );
+ }
+ if (__isShortFloat(aNumber)) {
+ result = __shortFloatVal(self) - __shortFloatVal(aNumber);
+ goto retResult;
+ }
+ if (__isFloatLike(aNumber)) {
+ dResult = (double) __shortFloatVal(self) - __floatVal(aNumber);
+ __qMKFLOAT(newFloat, dResult, SENDER);
+ RETURN ( newFloat );
+
+ }
+%}.
+ ^ aNumber differenceFromShortFloat:self
+!
+
+/ aNumber
+ "return the quotient of the receiver and the argument, aNumber"
+
+%{ /* NOCONTEXT */
+
+ OBJ newFloat;
+ float result, val;
+ double dResult, dVal;
+
+ if (__isSmallInteger(aNumber)) {
+ if (aNumber != __MKSMALLINT(0)) {
+ result = __shortFloatVal(self) / (float)(__intVal(aNumber));
+retResult:
+ __qMKSFLOAT(newFloat, result, SENDER);
+ RETURN ( newFloat );
+ }
+ }
+ if (__isShortFloat(aNumber)) {
+ val = __shortFloatVal(aNumber);
+ if (val != 0.0) {
+ result = __shortFloatVal(self) / val;
+ goto retResult;
+ }
+ }
+ if (__isFloatLike(aNumber)) {
+ dVal = __floatVal(aNumber);
+ if (dVal != 0.0) {
+ dResult = (double) __shortFloatVal(self) / dVal;
+ __qMKFLOAT(newFloat, dResult, SENDER);
+ }
+ RETURN ( newFloat );
+
+ }
+%}.
+ ((aNumber == 0) or:[aNumber = 0.0]) ifTrue:[
+ "
+ No, you shalt not divide by zero
+ "
+ ^ DivisionByZeroSignal raise.
+ ].
+ ^ aNumber quotientFromFloat:self
+
+!
+
+negated
+ "return myself negated"
+
+%{ /* NOCONTEXT */
+ OBJ newFloat;
+ float rslt = - __shortFloatVal(self);
+
+ __qMKSFLOAT(newFloat, rslt, SENDER);
+ RETURN ( newFloat );
+%}
+
+! !
+
+!ShortFloat methodsFor:'coercion and converting'!
+
+asFloat
+ "return a Float with same value as the receiver"
+
+%{ /* NOCONTEXT */
+
+ OBJ newFloat;
+ double dVal = (double)__shortFloatVal(self);
+
+ __qMKFLOAT(newFloat, dVal, SENDER);
+ RETURN ( newFloat );
+%}
+
+ "
+ 1.0 asShortFloat
+ "
+!
+
+asInteger
+ "return an integer with same value - might truncate"
+
+%{ /* NOCONTEXT */
+
+ if ((__shortFloatVal(self) >= (float)_MIN_INT)
+ && (__shortFloatVal(self) <= (float)_MAX_INT)) {
+ RETURN ( __MKSMALLINT( (INT)__shortFloatVal(self)) );
+ }
+%}.
+ ^ super asInteger
+
+ "
+ 12345.0 asShortFloat asInteger
+ 1e15 asShortFloat asInteger
+ "
+!
+
+asShortFloat
+ "return a ShortFloat with same value as the receiver - thats me"
+
+ ^ self
+! !
+
+!ShortFloat methodsFor:'comparing'!
+
+< aNumber
+ "return true, if the argument is greater"
+
+%{ /* NOCONTEXT */
+
+ if (__isSmallInteger(aNumber)) {
+ RETURN ( (__shortFloatVal(self) < (float)(__intVal(aNumber))) ? true : false );
+ }
+ if (__isFloatLike(aNumber)) {
+ RETURN ( (double)(__shortFloatVal(self) < __floatVal(aNumber)) ? true : false );
+ }
+ if (__isShortFloat(aNumber)) {
+ RETURN ( (__shortFloatVal(self) < __shortFloatVal(aNumber)) ? true : false );
+ }
+%}.
+ ^ aNumber lessFromShortFloat:self
+
+
+!
+
+<= aNumber
+ "return true, if the argument is greater or equal"
+
+%{ /* NOCONTEXT */
+
+ if (__isSmallInteger(aNumber)) {
+ RETURN ( (__shortFloatVal(self) <= (float)(__intVal(aNumber))) ? true : false );
+ }
+ if (__isFloatLike(aNumber)) {
+ RETURN ( (double)(__shortFloatVal(self) <= __floatVal(aNumber)) ? true : false );
+ }
+ if (__isShortFloat(aNumber)) {
+ RETURN ( (__shortFloatVal(self) <= __shortFloatVal(aNumber)) ? true : false );
+ }
+%}.
+ ^ self retry:#<= coercing:aNumber
+
+!
+
+= aNumber
+ "return true, if the arguments value are equal by value"
+
+%{ /* NOCONTEXT */
+
+ if (__isSmallInteger(aNumber)) {
+ RETURN ( (__shortFloatVal(self) == (float)(__intVal(aNumber))) ? true : false );
+ }
+ if (__isFloatLike(aNumber)) {
+ RETURN ( (double)(__shortFloatVal(self) == __floatVal(aNumber)) ? true : false );
+ }
+ if (__isShortFloat(aNumber)) {
+ RETURN ( (__shortFloatVal(self) == __shortFloatVal(aNumber)) ? true : false );
+ }
+%}.
+ ^ self retry:#= coercing:aNumber
+
+!
+
+> aNumber
+ "return true, if the argument is less"
+
+%{ /* NOCONTEXT */
+
+ if (__isSmallInteger(aNumber)) {
+ RETURN ( (__shortFloatVal(self) > (float)(__intVal(aNumber))) ? true : false );
+ }
+ if (__isFloatLike(aNumber)) {
+ RETURN ( (double)(__shortFloatVal(self) > __floatVal(aNumber)) ? true : false );
+ }
+ if (__isShortFloat(aNumber)) {
+ RETURN ( (__shortFloatVal(self) > __shortFloatVal(aNumber)) ? true : false );
+ }
+%}.
+ ^ self retry:#> coercing:aNumber
+!
+
+>= aNumber
+ "return true, if the argument is less or equal"
+
+%{ /* NOCONTEXT */
+
+ if (__isSmallInteger(aNumber)) {
+ RETURN ( (__shortFloatVal(self) >= (float)(__intVal(aNumber))) ? true : false );
+ }
+ if (__isFloatLike(aNumber)) {
+ RETURN ( (double)(__shortFloatVal(self) >= __floatVal(aNumber)) ? true : false );
+ }
+ if (__isShortFloat(aNumber)) {
+ RETURN ( (__shortFloatVal(self) >= __shortFloatVal(aNumber)) ? true : false );
+ }
+%}.
+ ^ self retry:#>= coercing:aNumber
+!
+
+hash
+ "return a number for hashing; redefined, since floats compare
+ by numeric value (i.e. 3.0 = 3), therefore 3.0 hash must be the same
+ as 3 hash."
+
+ |i|
+
+ (self >= SmallInteger minVal and:[self <= SmallInteger maxVal]) ifTrue:[
+ i := self asInteger.
+ self = i ifTrue:[
+ ^ i hash
+ ].
+ ].
+
+ "
+ mhmh take some of my value-bits to hash on
+ "
+ ^ (((self basicAt:4) bitAnd:16r3F) bitShift:24) +
+ ((self basicAt:3) bitShift:16) +
+ ((self basicAt:2) bitShift:8) +
+ (self basicAt:1)
+
+ "
+ 1.2345 hash
+ 1.2345 asShortFloat hash
+ 1.0 hash
+ 1.0 asShortFloat hash
+ "
+!
+
+~= aNumber
+ "return true, if the arguments value are not equal"
+
+%{ /* NOCONTEXT */
+
+ if (__isSmallInteger(aNumber)) {
+ RETURN ( (__shortFloatVal(self) != (float)(__intVal(aNumber))) ? true : false );
+ }
+ if (__isFloatLike(aNumber)) {
+ RETURN ( (double)(__shortFloatVal(self) != __floatVal(aNumber)) ? true : false );
+ }
+ if (__isShortFloat(aNumber)) {
+ RETURN ( (__shortFloatVal(self) != __shortFloatVal(aNumber)) ? true : false );
+ }
+%}.
+ ^ self retry:#~= coercing:aNumber
+
+! !
+
+!ShortFloat methodsFor:'printing & storing'!
+
+printString
+ "return a printed representation of the receiver"
+
+%{ /* NOCONTEXT */
+
+ char buffer[64];
+ REGISTER char *cp;
+ OBJ s;
+
+ /*
+ * actually only needed on sparc: since thisContext is
+ * in a global register, which gets destroyed by printf,
+ * manually save it here - very stupid ...
+ */
+ __BEGIN_PROTECT_REGISTERS__
+
+#ifdef SYSV
+ sprintf(buffer, "%.6lg", (double)__shortFloatVal(self));
+#else
+ sprintf(buffer, "%.6G", (double)__shortFloatVal(self));
+#endif
+
+ __END_PROTECT_REGISTERS__
+
+ /*
+ * kludge to make integral float f prints as "f.0" (not as "f" as printf does)
+ * (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++ = '.';
+ *cp++ = '0';
+ *cp = '\0';
+ }
+
+ s = __MKSTRING(buffer COMMA_SND);
+ if (s != nil) {
+ RETURN (s);
+ }
+%}.
+ "
+ memory allocation (for the new string) failed.
+ When we arrive here, there was no memory, even after a garbage collect.
+ This means, that the VM wanted to get some more memory from the
+ OS, which was not kind enough to give it.
+ Bad luck - you should increase the swap space on your machine.
+ "
+ ^ ObjectMemory allocationFailureSignal raise.
+! !
+
+!ShortFloat methodsFor:'testing'!
+
+negative
+ "return true if the receiver is less than zero"
+
+%{ /* NOCONTEXT */
+
+ RETURN ( (__shortFloatVal(self) < 0.0) ? true : false );
+%}
+
+
+!
+
+positive
+ "return true if the receiver is greater or equal to zero"
+
+%{ /* NOCONTEXT */
+
+ RETURN ( (__shortFloatVal(self) >= 0.0) ? true : false );
+%}
+
+! !
+
+!ShortFloat class methodsFor:'documentation'!
+
+version
+ ^ '$Header: /cvs/stx/stx/libbasic/ShortFloat.st,v 1.1 1996-04-17 10:30:43 cg Exp $'
+! !