# HG changeset patch # User Claus Gittinger # Date 829737043 -7200 # Node ID 2b37cf664b811b9950894366f991b0f20c57cb64 # Parent 7b3eeec128d3371a5d4da143c2b5309b92f3658a intitial checkin diff -r 7b3eeec128d3 -r 2b37cf664b81 SFloat.st --- /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 $' +! ! diff -r 7b3eeec128d3 -r 2b37cf664b81 ShortFloat.st --- /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 $' +! !