diff -r 6fb9813181cc -r 8697e2333da3 ShortFloat.st --- a/ShortFloat.st Wed Sep 16 19:07:58 2009 +0200 +++ b/ShortFloat.st Wed Sep 16 19:08:24 2009 +0200 @@ -63,26 +63,26 @@ */ # ifndef isnan # define isnan(x) \ - ((((unsigned int *)(&x))[0] == 0x00000000) && \ - (((unsigned int *)(&x))[1] == 0xFFF80000)) + ((((unsigned int *)(&x))[0] == 0x00000000) && \ + (((unsigned int *)(&x))[1] == 0xFFF80000)) # endif # ifndef isPositiveInfinity # define isPositiveInfinity(x) \ - ((((unsigned int *)(&x))[0] == 0x00000000) && \ - (((unsigned int *)(&x))[1] == 0x7FF00000)) + ((((unsigned int *)(&x))[0] == 0x00000000) && \ + (((unsigned int *)(&x))[1] == 0x7FF00000)) # endif # ifndef isNegativeInfinity # define isPositiveInfinity(x) \ - ((((unsigned int *)(&x))[0] == 0x00000000) && \ - (((unsigned int *)(&x))[1] == 0xFFF00000)) + ((((unsigned int *)(&x))[0] == 0x00000000) && \ + (((unsigned int *)(&x))[1] == 0xFFF00000)) # endif # ifndef isinf # define isinf(x) \ - ((((unsigned int *)(&x))[0] == 0x00000000) && \ - ((((unsigned int *)(&x))[1] & 0x7FF00000) == 0x7FF00000)) + ((((unsigned int *)(&x))[0] == 0x00000000) && \ + ((((unsigned int *)(&x))[1] & 0x7FF00000) == 0x7FF00000)) # endif # ifndef isfinite @@ -91,22 +91,22 @@ # ifndef isnanf # define isnanf(x) \ - (((unsigned int *)(&x))[0] == 0xFFC00000) + (((unsigned int *)(&x))[0] == 0xFFC00000) # endif # ifndef isPositiveInfinityf # define isPositiveInfinityf(x) \ - (((unsigned int *)(&x))[0] == 0x7F800000) + (((unsigned int *)(&x))[0] == 0x7F800000) # endif # ifndef isNegativeInfinityf # define isNegativeInfinityf(x) \ - (((unsigned int *)(&x))[0] == 0xFF800000) + (((unsigned int *)(&x))[0] == 0xFF800000) # endif # ifndef isinff # define isinff(x) \ - ((((unsigned int *)(&x))[0] & 0x7FFFFFFF) == 0x7F800000) + ((((unsigned int *)(&x))[0] & 0x7FFFFFFF) == 0x7F800000) # endif # ifndef isfinitef @@ -160,7 +160,7 @@ documentation " - ShortFloats represent rational numbers with limited precision. + ShortFloats represent rational numbers with limited precision. They use the C-compilers 'float' format, which is usually the IEE single float format. In contrast to Floats (which use the C-compilers 64bit 'double' format), @@ -168,42 +168,42 @@ 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 + 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 some of 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. + 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 some of 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. Mixed mode arithmetic: - shortFloat op shortFloat -> shortFloat - shortFloat op fix -> shortFloat - shortFloat op fraction -> shortFloat - shortFloat op integer -> shortFloat - shortFloat op longFloat -> longFloat - shortFloat op float -> float - shortFloat op complex -> complex + shortFloat op shortFloat -> shortFloat + shortFloat op fix -> shortFloat + shortFloat op fraction -> shortFloat + shortFloat op integer -> shortFloat + shortFloat op longFloat -> longFloat + shortFloat op float -> float + shortFloat op complex -> complex Representation: - 32bit single precision IEE floats - 23 bit mantissa, - 8 bit exponent, - 6 decimal digits (approx) + 32bit single precision IEE floats + 23 bit mantissa, + 8 bit exponent, + 6 decimal digits (approx) Range and Precision of Storage Formats: see LimitedPrecisionReal >> documentation [author:] - Claus Gittinger + Claus Gittinger [see also:] - Number - Float LongFloat Fraction FixedPoint Integer Complex - FloatArray DoubleArray + Number + Float LongFloat Fraction FixedPoint Integer Complex + FloatArray DoubleArray " ! ! @@ -215,7 +215,7 @@ Its implemented here to allow things like binary store & load of shortFloats. (but even this support will go away eventually, its not a good idea to store the bits of a float - the reader might have a - totally different representation - so floats will eventually be + totally different representation - so floats will eventually be binary stored in a device independent format." %{ /* NOCONTEXT */ @@ -227,14 +227,15 @@ ! fastFromString:aString at:startIndex - "return the next ShortFloat from the string starting at startIndex. + "return the next ShortFloat from the string starting at startIndex. No spaces are skipped. This is a specially tuned entry (using a low-level C-call), which returns garbage if the argument string is not a valid float number. - It has been added to allow higher speed string decomposition into - numbers." -%{ + It has been added to allow higher speed string decomposition into numbers, + especially for mass-data." + +%{ /* NOCONTEXT */ if (__isString(aString) && __isSmallInteger(startIndex)) { char *cp = (char *)(__stringVal(aString)); int idx = __intVal(startIndex) - 1; @@ -250,18 +251,18 @@ self primitiveFailed. " - ShortFloat fastFromString:'123.45' at:1 - ShortFloat fastFromString:'123.45' at:2 - ShortFloat fastFromString:'123.45E4' at:1 - ShortFloat fastFromString:'hello123.45E4' at:6 - ShortFloat fastFromString:'12345' at:1 - ShortFloat fastFromString:'12345' at:2 - ShortFloat fastFromString:'12345' at:3 - ShortFloat fastFromString:'12345' at:4 - ShortFloat fastFromString:'12345' at:5 - ShortFloat fastFromString:'12345' at:6 - ShortFloat fastFromString:'12345' at:0 - ShortFloat fastFromString:'hello123.45E4' at:1 + ShortFloat fastFromString:'123.45' at:1 + ShortFloat fastFromString:'123.45' at:2 + ShortFloat fastFromString:'123.45E4' at:1 + ShortFloat fastFromString:'hello123.45E4' at:6 + ShortFloat fastFromString:'12345' at:1 + ShortFloat fastFromString:'12345' at:2 + ShortFloat fastFromString:'12345' at:3 + ShortFloat fastFromString:'12345' at:4 + ShortFloat fastFromString:'12345' at:5 + ShortFloat fastFromString:'12345' at:6 + ShortFloat fastFromString:'12345' at:0 + ShortFloat fastFromString:'hello123.45E4' at:1 Time millisecondsToRun:[ 100000 timesRepeat:[ @@ -273,7 +274,7 @@ " Time millisecondsToRun:[ 100000 timesRepeat:[ - ShortFloat fastFromString:'123.45' at:1 + ShortFloat fastFromString:'123.45' at:1 ] ] " @@ -288,17 +289,17 @@ |num| num := super readFrom:aStringOrStream onError:[self error:'conversion error for: ' , self name]. - num notNil ifTrue:[ + num notNil ifTrue:[ num := num asShortFloat ]. - ^ num + ^ num " ShortFloat readFrom:'0.1' - ShortFloat readFrom:'0' - ShortFloat readFrom:'.123' - ShortFloat readFrom:'-.123' - ShortFloat readFrom:'1e4' + ShortFloat readFrom:'0' + ShortFloat readFrom:'.123' + ShortFloat readFrom:'-.123' + ShortFloat readFrom:'1e4' " "Modified: / 7.1.1998 / 16:17:59 / cg" @@ -310,7 +311,7 @@ |num| num := super readFrom:aStringOrStream onError:nil. - num isNil ifTrue:[ + num isNil ifTrue:[ ^ exceptionBlock value ]. ^ num asShortFloat @@ -356,14 +357,14 @@ self isIEEEFormat ifFalse:[self error:'unsupported operation']. UninterpretedBytes isBigEndian ifFalse:[ - "swap the bytes" - 8 to:4 by:-1 do:[:i | - aFloat basicAt:i put:(aStream next) - ]. - ^ self + "swap the bytes" + 8 to:4 by:-1 do:[:i | + aFloat basicAt:i put:(aStream next) + ]. + ^ self ]. 1 to:4 do:[:i | - aFloat basicAt:i put:aStream next + aFloat basicAt:i put:aStream next ] "not part of libboss, as this is also used by others (TIFFReader)" @@ -387,14 +388,14 @@ self isIEEEFormat ifFalse:[self error:'unsupported operation']. UninterpretedBytes isBigEndian ifFalse:[ - "swap the bytes" - 8 to:4 by:-1 do:[:i | - aStream nextPut:(float basicAt:i). - ]. - ^ self + "swap the bytes" + 8 to:4 by:-1 do:[:i | + aStream nextPut:(float basicAt:i). + ]. + ^ self ]. 1 to:4 do:[:i | - aStream nextPut:(float basicAt:i). + aStream nextPut:(float basicAt:i). ] "not part of libboss, as this is also used by others (TIFFReader)" @@ -462,7 +463,7 @@ numBitsInExponent "answer the number of bits in the exponent This is an IEEE float, where 8 bits are available: - seeeeeee emmmmmmm mmmmmmmm mmmmmmmm + seeeeeee emmmmmmm mmmmmmmm mmmmmmmm " ^ 8 @@ -471,7 +472,7 @@ numBitsInMantissa "answer the number of bits in the mantissa. This is an IEEE float, where 23 bits (the hidden one is not counted here) are available: - seeeeeee emmmmmmm mmmmmmmm mmmmmmmm + seeeeeee emmmmmmm mmmmmmmm mmmmmmmm " ^ 23 @@ -479,7 +480,7 @@ precision "answer the precision of a ShortFloat (in bits) - This is an IEEE float, where only the fraction from the normalized mantissa is stored + This is an IEEE float, where only the fraction from the normalized mantissa is stored and so there is a hidden bit and the mantissa is actually represented by 24 binary digits (although only 23 are needed in the binary representation)" @@ -505,19 +506,19 @@ double dResult; if (__isSmallInteger(aNumber)) { - result = __shortFloatVal(self) * (float)(__intVal(aNumber)); + result = __shortFloatVal(self) * (float)(__intVal(aNumber)); retResult: - __qMKSFLOAT(newFloat, result); - RETURN ( newFloat ); - } + __qMKSFLOAT(newFloat, result); + RETURN ( newFloat ); + } if (__isShortFloat(aNumber)) { - result = __shortFloatVal(self) * __shortFloatVal(aNumber); - goto retResult; - } + result = __shortFloatVal(self) * __shortFloatVal(aNumber); + goto retResult; + } if (__isFloatLike(aNumber)) { - dResult = (double) __shortFloatVal(self)* __floatVal(aNumber); - __qMKFLOAT(newFloat, dResult); - RETURN ( newFloat ); + dResult = (double) __shortFloatVal(self)* __floatVal(aNumber); + __qMKFLOAT(newFloat, dResult); + RETURN ( newFloat ); } %}. ^ aNumber productFromShortFloat:self @@ -533,19 +534,19 @@ double dResult; if (__isSmallInteger(aNumber)) { - result = __shortFloatVal(self) + (float)(__intVal(aNumber)); + result = __shortFloatVal(self) + (float)(__intVal(aNumber)); retResult: - __qMKSFLOAT(newFloat, result); - RETURN ( newFloat ); - } + __qMKSFLOAT(newFloat, result); + RETURN ( newFloat ); + } if (__isShortFloat(aNumber)) { - result = __shortFloatVal(self) + __shortFloatVal(aNumber); - goto retResult; - } + result = __shortFloatVal(self) + __shortFloatVal(aNumber); + goto retResult; + } if (__isFloatLike(aNumber)) { - dResult = (double) __shortFloatVal(self) + __floatVal(aNumber); - __qMKFLOAT(newFloat, dResult); - RETURN ( newFloat ); + dResult = (double) __shortFloatVal(self) + __floatVal(aNumber); + __qMKFLOAT(newFloat, dResult); + RETURN ( newFloat ); } %}. ^ aNumber sumFromShortFloat:self @@ -561,19 +562,19 @@ double dResult; if (__isSmallInteger(aNumber)) { - result = __shortFloatVal(self) - (float)(__intVal(aNumber)); + result = __shortFloatVal(self) - (float)(__intVal(aNumber)); retResult: - __qMKSFLOAT(newFloat, result); - RETURN ( newFloat ); - } + __qMKSFLOAT(newFloat, result); + RETURN ( newFloat ); + } if (__isShortFloat(aNumber)) { - result = __shortFloatVal(self) - __shortFloatVal(aNumber); - goto retResult; - } + result = __shortFloatVal(self) - __shortFloatVal(aNumber); + goto retResult; + } if (__isFloatLike(aNumber)) { - dResult = (double) __shortFloatVal(self) - __floatVal(aNumber); - __qMKFLOAT(newFloat, dResult); - RETURN ( newFloat ); + dResult = (double) __shortFloatVal(self) - __floatVal(aNumber); + __qMKFLOAT(newFloat, dResult); + RETURN ( newFloat ); } %}. ^ aNumber differenceFromShortFloat:self @@ -589,34 +590,34 @@ double dResult, dVal; if (__isSmallInteger(aNumber)) { - if (aNumber != __mkSmallInteger(0)) { - result = __shortFloatVal(self) / (float)(__intVal(aNumber)); + if (aNumber != __mkSmallInteger(0)) { + result = __shortFloatVal(self) / (float)(__intVal(aNumber)); retResult: - __qMKSFLOAT(newFloat, result); - RETURN ( newFloat ); - } - } + __qMKSFLOAT(newFloat, result); + RETURN ( newFloat ); + } + } if (__isShortFloat(aNumber)) { - val = __shortFloatVal(aNumber); - if (val != 0.0) { - result = __shortFloatVal(self) / val; - goto retResult; - } - } + 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); - RETURN ( newFloat ); - } + dVal = __floatVal(aNumber); + if (dVal != 0.0) { + dResult = (double) __shortFloatVal(self) / dVal; + __qMKFLOAT(newFloat, dResult); + RETURN ( newFloat ); + } } %}. ((aNumber == 0) or:[aNumber = 0.0]) ifTrue:[ - " - No, you shalt not divide by zero - " - ^ ZeroDivide raiseRequestWith:thisContext. + " + No, you shalt not divide by zero + " + ^ ZeroDivide raiseRequestWith:thisContext. ]. ^ aNumber quotientFromShortFloat:self ! @@ -631,8 +632,8 @@ float val = __shortFloatVal(self); if (val < 0.0) { - __qMKSFLOAT(newFloat, -val); - RETURN ( newFloat ); + __qMKSFLOAT(newFloat, -val); + RETURN ( newFloat ); } RETURN (self); %}. @@ -671,21 +672,21 @@ double dResult, dVal; if (__isSmallInteger(aNumber)) { - result = __shortFloatVal(self) / (float)(__intVal(aNumber)); + result = __shortFloatVal(self) / (float)(__intVal(aNumber)); retResult: - __qMKSFLOAT(newFloat, result); - RETURN ( newFloat ); - } + __qMKSFLOAT(newFloat, result); + RETURN ( newFloat ); + } if (__isShortFloat(aNumber)) { - val = __shortFloatVal(aNumber); - result = __shortFloatVal(self) / val; - goto retResult; - } + val = __shortFloatVal(aNumber); + result = __shortFloatVal(self) / val; + goto retResult; + } if (__isFloatLike(aNumber)) { - dVal = __floatVal(aNumber); - dResult = (double) __shortFloatVal(self) / dVal; - __qMKFLOAT(newFloat, dResult); - RETURN ( newFloat ); + dVal = __floatVal(aNumber); + dResult = (double) __shortFloatVal(self) / dVal; + __qMKFLOAT(newFloat, dResult); + RETURN ( newFloat ); } %}. ^ aNumber quotientFromShortFloat:self @@ -712,7 +713,7 @@ %} " - 1.0 asShortFloat asFloat + 1.0 asShortFloat asFloat " ! @@ -724,12 +725,12 @@ fVal = __shortFloatVal(self); #ifdef WIN32 - if (! isnanf(fVal)) + if (! isnanf(fVal)) #endif { - if ((fVal >= (float)_MIN_INT) && (fVal <= (float)_MAX_INT)) { - RETURN ( __mkSmallInteger( (INT)fVal) ); - } + if ((fVal >= (float)_MIN_INT) && (fVal <= (float)_MAX_INT)) { + RETURN ( __mkSmallInteger( (INT)fVal) ); + } } %}. ^ super asInteger @@ -772,15 +773,15 @@ %{ /* NOCONTEXT */ if (__isSmallInteger(aNumber)) { - RETURN ( (__shortFloatVal(self) < (float)(__intVal(aNumber))) ? true : false ); + RETURN ( (__shortFloatVal(self) < (float)(__intVal(aNumber))) ? true : false ); } if (aNumber != nil) { - if (__qIsFloatLike(aNumber)) { - RETURN ( (double)(__shortFloatVal(self) < __floatVal(aNumber)) ? true : false ); - } - if (__qIsShortFloat(aNumber)) { - RETURN ( (__shortFloatVal(self) < __shortFloatVal(aNumber)) ? true : false ); - } + if (__qIsFloatLike(aNumber)) { + RETURN ( (double)(__shortFloatVal(self) < __floatVal(aNumber)) ? true : false ); + } + if (__qIsShortFloat(aNumber)) { + RETURN ( (__shortFloatVal(self) < __shortFloatVal(aNumber)) ? true : false ); + } } %}. ^ aNumber lessFromShortFloat:self @@ -796,16 +797,16 @@ %{ /* NOCONTEXT */ if (__isSmallInteger(aNumber)) { - RETURN ( (__shortFloatVal(self) <= (float)(__intVal(aNumber))) ? true : false ); + RETURN ( (__shortFloatVal(self) <= (float)(__intVal(aNumber))) ? true : false ); } if (aNumber != nil) { - if (__qIsFloatLike(aNumber)) { - RETURN ( (double)(__shortFloatVal(self) <= __floatVal(aNumber)) ? true : false ); - } - if (__qIsShortFloat(aNumber)) { - RETURN ( (__shortFloatVal(self) <= __shortFloatVal(aNumber)) ? true : false ); - } - } + if (__qIsFloatLike(aNumber)) { + RETURN ( (double)(__shortFloatVal(self) <= __floatVal(aNumber)) ? true : false ); + } + if (__qIsShortFloat(aNumber)) { + RETURN ( (__shortFloatVal(self) <= __shortFloatVal(aNumber)) ? true : false ); + } + } %}. ^ self retry:#<= coercing:aNumber ! @@ -817,16 +818,16 @@ %{ /* NOCONTEXT */ if (__isSmallInteger(aNumber)) { - RETURN ( (__shortFloatVal(self) == (float)(__intVal(aNumber))) ? true : false ); + RETURN ( (__shortFloatVal(self) == (float)(__intVal(aNumber))) ? true : false ); } if (aNumber == nil) { - RETURN (false); + RETURN (false); } if (__qIsFloatLike(aNumber)) { - RETURN ( (double)(__shortFloatVal(self) == __floatVal(aNumber)) ? true : false ); + RETURN ( (double)(__shortFloatVal(self) == __floatVal(aNumber)) ? true : false ); } if (__qIsShortFloat(aNumber)) { - RETURN ( (__shortFloatVal(self) == __shortFloatVal(aNumber)) ? true : false ); + RETURN ( (__shortFloatVal(self) == __shortFloatVal(aNumber)) ? true : false ); } %}. ^ aNumber equalFromShortFloat:self @@ -838,15 +839,15 @@ %{ /* NOCONTEXT */ if (__isSmallInteger(aNumber)) { - RETURN ( (__shortFloatVal(self) > (float)(__intVal(aNumber))) ? true : false ); + RETURN ( (__shortFloatVal(self) > (float)(__intVal(aNumber))) ? true : false ); } if (aNumber != nil) { - if (__qIsFloatLike(aNumber)) { - RETURN ( (double)(__shortFloatVal(self) > __floatVal(aNumber)) ? true : false ); - } - if (__qIsShortFloat(aNumber)) { - RETURN ( (__shortFloatVal(self) > __shortFloatVal(aNumber)) ? true : false ); - } + if (__qIsFloatLike(aNumber)) { + RETURN ( (double)(__shortFloatVal(self) > __floatVal(aNumber)) ? true : false ); + } + if (__qIsShortFloat(aNumber)) { + RETURN ( (__shortFloatVal(self) > __shortFloatVal(aNumber)) ? true : false ); + } } %}. ^ self retry:#> coercing:aNumber @@ -858,15 +859,15 @@ %{ /* NOCONTEXT */ if (__isSmallInteger(aNumber)) { - RETURN ( (__shortFloatVal(self) >= (float)(__intVal(aNumber))) ? true : false ); + RETURN ( (__shortFloatVal(self) >= (float)(__intVal(aNumber))) ? true : false ); } if (aNumber != nil) { - if (__qIsFloatLike(aNumber)) { - RETURN ( (double)(__shortFloatVal(self) >= __floatVal(aNumber)) ? true : false ); - } - if (__qIsShortFloat(aNumber)) { - RETURN ( (__shortFloatVal(self) >= __shortFloatVal(aNumber)) ? true : false ); - } + if (__qIsFloatLike(aNumber)) { + RETURN ( (double)(__shortFloatVal(self) >= __floatVal(aNumber)) ? true : false ); + } + if (__qIsShortFloat(aNumber)) { + RETURN ( (__shortFloatVal(self) >= __shortFloatVal(aNumber)) ? true : false ); + } } %}. ^ self retry:#>= coercing:aNumber @@ -889,14 +890,14 @@ ^ self asFloat hash " - 1.2345 hash - 1.2345 asShortFloat hash - 1.0 hash - 1.0 asShortFloat hash - 0.5 asShortFloat hash - 0.25 asShortFloat hash - 0.5 hash - 0.25 hash + 1.2345 hash + 1.2345 asShortFloat hash + 1.0 hash + 1.0 asShortFloat hash + 0.5 asShortFloat hash + 0.25 asShortFloat hash + 0.5 hash + 0.25 hash " ! @@ -906,17 +907,17 @@ %{ /* NOCONTEXT */ if (aNumber != nil) { - if (__isSmallInteger(aNumber)) { - RETURN ( (__shortFloatVal(self) != (float)(__intVal(aNumber))) ? true : false ); - } - if (__qIsFloatLike(aNumber)) { - RETURN ( (double)(__shortFloatVal(self) != __floatVal(aNumber)) ? true : false ); - } - if (__qIsShortFloat(aNumber)) { - RETURN ( (__shortFloatVal(self) != __shortFloatVal(aNumber)) ? true : false ); - } + if (__isSmallInteger(aNumber)) { + RETURN ( (__shortFloatVal(self) != (float)(__intVal(aNumber))) ? true : false ); + } + if (__qIsFloatLike(aNumber)) { + RETURN ( (double)(__shortFloatVal(self) != __floatVal(aNumber)) ? true : false ); + } + if (__qIsShortFloat(aNumber)) { + RETURN ( (__shortFloatVal(self) != __shortFloatVal(aNumber)) ? true : false ); + } } else { - RETURN ( true ); + RETURN ( true ); } %}. ^ super ~= aNumber @@ -952,55 +953,55 @@ __END_PROTECT_REGISTERS__ if (len >= 0 && len <= sizeof(buffer)-3) { - /* - * 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') || (*cp == 'e')) break; - } - if (!*cp && (cp[-1] >= '0') && (cp[-1] <= '9')) { - if (__isCharacter(@global(DecimalPointCharacterForPrinting))) { - *cp++ = __intVal(__characterVal(@global(DecimalPointCharacterForPrinting))); - } else { - *cp++ = '.'; - } - *cp++ = '0'; - *cp = '\0'; - } else { - if (cp && (*cp == '.')) { - if (__isCharacter(@global(DecimalPointCharacterForPrinting))) { - *cp = __intVal(__characterVal(@global(DecimalPointCharacterForPrinting))); - } - } - } + /* + * 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') || (*cp == 'e')) break; + } + if (!*cp && (cp[-1] >= '0') && (cp[-1] <= '9')) { + if (__isCharacter(@global(DecimalPointCharacterForPrinting))) { + *cp++ = __intVal(__characterVal(@global(DecimalPointCharacterForPrinting))); + } else { + *cp++ = '.'; + } + *cp++ = '0'; + *cp = '\0'; + } else { + if (cp && (*cp == '.')) { + if (__isCharacter(@global(DecimalPointCharacterForPrinting))) { + *cp = __intVal(__characterVal(@global(DecimalPointCharacterForPrinting))); + } + } + } - s = __MKSTRING(buffer); - if (s != nil) { - RETURN (s); - } + s = __MKSTRING(buffer); + if (s != nil) { + RETURN (s); + } } %}. ^ self asFloat printString " - 1.234 asShortFloat printString. - 1.0 asShortFloat printString. - 1e10 asShortFloat printString. - 1.2e3 asShortFloat printString. - 1.2e30 asShortFloat printString. - (1.0 uncheckedDivide:0) asShortFloat printString. - (0.0 uncheckedDivide:0) asShortFloat printString. + 1.234 asShortFloat printString. + 1.0 asShortFloat printString. + 1e10 asShortFloat printString. + 1.2e3 asShortFloat printString. + 1.2e30 asShortFloat printString. + (1.0 uncheckedDivide:0) asShortFloat printString. + (0.0 uncheckedDivide:0) asShortFloat printString. - DecimalPointCharacterForPrinting := $,. - 1.234 asShortFloat printString. - 1.0 asShortFloat printString. - 1e10 asShortFloat printString. - 1.2e3 asShortFloat printString. - 1.2e30 asShortFloat printString. - (1.0 uncheckedDivide:0) asShortFloat printString. - (0.0 uncheckedDivide:0) asShortFloat printString. - DecimalPointCharacterForPrinting := $. + DecimalPointCharacterForPrinting := $,. + 1.234 asShortFloat printString. + 1.0 asShortFloat printString. + 1e10 asShortFloat printString. + 1.2e3 asShortFloat printString. + 1.2e30 asShortFloat printString. + (1.0 uncheckedDivide:0) asShortFloat printString. + (0.0 uncheckedDivide:0) asShortFloat printString. + DecimalPointCharacterForPrinting := $. " ! @@ -1008,7 +1009,7 @@ "non-standard: return a printed representation of the receiver as specified by formatString, which is defined by printf. If you use this, be aware, that specifying doubles differs on - systems; on SYSV machines you have to give something like %lf, + systems; on SYSV machines you have to give something like %lf, while on BSD systems the format string has to be %F. Also, the resulting string may not be longer than 255 bytes - since thats the (static) size of the buffer. @@ -1022,23 +1023,23 @@ int len; if (__isString(formatString)) { - /* - * 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__ + /* + * 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__ - len = snprintf(buffer, sizeof(buffer), __stringVal(formatString), __shortFloatVal(self)); + len = snprintf(buffer, sizeof(buffer), __stringVal(formatString), __shortFloatVal(self)); - __END_PROTECT_REGISTERS__ + __END_PROTECT_REGISTERS__ - if (len < 0) goto fail; + if (len < 0) goto fail; - s = __MKSTRING_L(buffer, len); - if (s != nil) { - RETURN (s); - } + s = __MKSTRING_L(buffer, len); + if (s != nil) { + RETURN (s); + } } fail: ; %}. @@ -1079,23 +1080,23 @@ __END_PROTECT_REGISTERS__ if (len >= 0 && len < sizeof(buffer)-3) { - /* - * 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') || (*cp == 'e')) break; - } - if (!*cp && (cp[-1] >= '0') && (cp[-1] <= '9')) { - *cp++ = '.'; - *cp++ = '0'; - *cp = '\0'; - } + /* + * 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') || (*cp == 'e')) break; + } + if (!*cp && (cp[-1] >= '0') && (cp[-1] <= '9')) { + *cp++ = '.'; + *cp++ = '0'; + *cp = '\0'; + } - s = __MKSTRING(buffer); - if (s != nil) { - RETURN (s); - } + s = __MKSTRING(buffer); + if (s != nil) { + RETURN (s); + } } %}. " @@ -1108,26 +1109,26 @@ ^ ObjectMemory allocationFailureSignal raise. " - 1.0 asShortFloat storeString - 1.234 asShortFloat storeString - 1e10 asShortFloat storeString - 1.2e3 asShortFloat storeString - 1.2e30 asShortFloat storeString - Float pi asShortFloat storeString - (1.0 uncheckedDivide:0) asShortFloat storeString - (0.0 uncheckedDivide:0) asShortFloat storeString + 1.0 asShortFloat storeString + 1.234 asShortFloat storeString + 1e10 asShortFloat storeString + 1.2e3 asShortFloat storeString + 1.2e30 asShortFloat storeString + Float pi asShortFloat storeString + (1.0 uncheckedDivide:0) asShortFloat storeString + (0.0 uncheckedDivide:0) asShortFloat storeString notice that the storeString is NOT affected by DecimalPointCharacterForPrinting: - DecimalPointCharacterForPrinting := $,. - 1.234 asShortFloat storeString. - 1.0 asShortFloat storeString. - 1e10 asShortFloat storeString. - 1.2e3 asShortFloat storeString. - 1.2e30 asShortFloat storeString. - (1.0 uncheckedDivide:0) asShortFloat storeString. - (0.0 uncheckedDivide:0) asShortFloat storeString. - DecimalPointCharacterForPrinting := $. + DecimalPointCharacterForPrinting := $,. + 1.234 asShortFloat storeString. + 1.0 asShortFloat storeString. + 1e10 asShortFloat storeString. + 1.2e3 asShortFloat storeString. + 1.2e30 asShortFloat storeString. + (1.0 uncheckedDivide:0) asShortFloat storeString. + (0.0 uncheckedDivide:0) asShortFloat storeString. + DecimalPointCharacterForPrinting := $. " ! ! @@ -1153,18 +1154,18 @@ frexp( (double)(__shortFloatVal(self)), &exp); #endif if (__threadErrno == 0) { - RETURN (__mkSmallInteger(exp)); + RETURN (__mkSmallInteger(exp)); } %}. ^ super exponent " - 4.0 asShortFloat exponent - 2.0 asShortFloat exponent - 1.0 asShortFloat exponent - 0.5 asShortFloat exponent - 0.25 asShortFloat exponent - 0.00000011111 asShortFloat exponent + 4.0 asShortFloat exponent + 2.0 asShortFloat exponent + 1.0 asShortFloat exponent + 0.5 asShortFloat exponent + 0.25 asShortFloat exponent + 0.00000011111 asShortFloat exponent " ! @@ -1185,7 +1186,7 @@ __threadErrno = 0; frac = frexpf( (double)__shortFloatVal(self), &exp); if (__threadErrno == 0) { - RETURN (__MKSFLOAT(frac)); + RETURN (__MKSFLOAT(frac)); } #else double frexp(); @@ -1194,31 +1195,31 @@ __threadErrno = 0; frac = frexp( (double)(__shortFloatVal(self)), &exp); if (__threadErrno == 0) { - RETURN (__MKFLOAT(frac)); + RETURN (__MKFLOAT(frac)); } #endif %}. ^ self primitiveFailed " - 1.0 asShortFloat exponent + 1.0 asShortFloat exponent 1.0 asShortFloat mantissa - 0.5 asShortFloat exponent - 0.5 asShortFloat mantissa + 0.5 asShortFloat exponent + 0.5 asShortFloat mantissa - 0.25 asShortFloat exponent - 0.25 asShortFloat mantissa + 0.25 asShortFloat exponent + 0.25 asShortFloat mantissa - 0.00000011111 asShortFloat exponent - 0.00000011111 asShortFloat mantissa + 0.00000011111 asShortFloat exponent + 0.00000011111 asShortFloat mantissa " ! ! !ShortFloat methodsFor:'testing'! isFinite - "return true, if the receiver is a finite float + "return true, if the receiver is a finite float i.e. not NaN and not infinite." %{ /* NOCONTEXT */ @@ -1226,7 +1227,7 @@ /* * notice: on machines which do not provide - * a isfinite() macro or function (WIN32), + * a isfinite() macro or function (WIN32), * this may always ret true here ... */ if (isfinitef(fV)) { RETURN (true); } @@ -1234,9 +1235,9 @@ ^ false " - 1.0 asShortFloat isFinite - (0.0 asShortFloat uncheckedDivide: 0.0) isFinite - (1.0 asShortFloat uncheckedDivide: 0.0) isFinite + 1.0 asShortFloat isFinite + (0.0 asShortFloat uncheckedDivide: 0.0) isFinite + (1.0 asShortFloat uncheckedDivide: 0.0) isFinite " ! @@ -1250,7 +1251,7 @@ /* * notice: on machines which do not provide - * a isnan() macro or function (WIN32), + * a isnan() macro or function (WIN32), * this may always ret false here ... */ if (isnanf(sV)) { RETURN (true); } @@ -1259,8 +1260,8 @@ " 1.0 asShortFloat isNaN - (0.0 asShortFloat uncheckedDivide: 0.0) isNaN - (0.0 asShortFloat uncheckedDivide: 0.0 asShortFloat) isNaN + (0.0 asShortFloat uncheckedDivide: 0.0) isNaN + (0.0 asShortFloat uncheckedDivide: 0.0 asShortFloat) isNaN " ! @@ -1275,8 +1276,8 @@ ^ super isNegativeZero " - 0.0 asShortFloat isNegativeZero - -0.0 asShortFloat isNegativeZero + 0.0 asShortFloat isNegativeZero + -0.0 asShortFloat isNegativeZero " ! @@ -1300,8 +1301,8 @@ %} " - 1.2 numberOfBits - 1.2 asShortFloat numberOfBits + 1.2 numberOfBits + 1.2 asShortFloat numberOfBits " ! @@ -1343,21 +1344,21 @@ * ST-80 (and X3J20) returns integer. */ if ((fVal >= (float)_MIN_INT) && (fVal <= (float)_MAX_INT)) { - RETURN ( __mkSmallInteger( (INT) fVal ) ); + RETURN ( __mkSmallInteger( (INT) fVal ) ); } __qMKSFLOAT(val, fVal); %}. ^ val asInteger " - 0.5 asShortFloat ceiling - -0.5 asShortFloat ceiling + 0.5 asShortFloat ceiling + -0.5 asShortFloat ceiling " ! ceilingAsFloat "return the smallest integer-valued float greater or equal to the receiver. - This is much like #ceiling, but avoids a (possibly expensive) conversion + This is much like #ceiling, but avoids a (possibly expensive) conversion of the result to an integer. It may be useful, if the result is to be further used in another float-operation." @@ -1374,9 +1375,9 @@ RETURN (v); %} " - 0.5 asShortFloat ceilingAsFloat - -0.5 asShortFloat ceilingAsFloat - -1.5 asShortFloat ceilingAsFloat + 0.5 asShortFloat ceilingAsFloat + -0.5 asShortFloat ceilingAsFloat + -1.5 asShortFloat ceilingAsFloat " ! @@ -1397,15 +1398,15 @@ * ST-80 (and X3J20) returns integer. */ if ((fVal >= (float)_MIN_INT) && (fVal <= (float)_MAX_INT)) { - RETURN ( __mkSmallInteger( (INT) fVal ) ); + RETURN ( __mkSmallInteger( (INT) fVal ) ); } __qMKSFLOAT(val, fVal); %}. ^ val asInteger " - 0.5 asShortFloat floor - -0.5 asShortFloat floor + 0.5 asShortFloat floor + -0.5 asShortFloat floor " ! @@ -1429,8 +1430,8 @@ %} " - 0.5 asShortFloat floorAsFloat - -0.5 asShortFloat floorAsFloat + 0.5 asShortFloat floorAsFloat + -0.5 asShortFloat floorAsFloat " ! @@ -1445,29 +1446,29 @@ __threadErrno = 0; frac = modf((double)(__shortFloatVal(self)), &trunc); - if (! isnan(frac)) { - if (__threadErrno == 0) { - RETURN (__MKSFLOAT((float)frac)); - } + if (! isnan(frac)) { + if (__threadErrno == 0) { + RETURN (__MKSFLOAT((float)frac)); + } } %}. ^ self class - raise:#domainErrorSignal - receiver:self - selector:#fractionPart - arguments:#() - errorString:'bad receiver in fractionPart' + raise:#domainErrorSignal + receiver:self + selector:#fractionPart + arguments:#() + errorString:'bad receiver in fractionPart' " - 1.6 asShortFloat fractionPart + 1.6 asShortFloat truncated - -1.6 asShortFloat fractionPart + -1.6 asShortFloat truncated + 1.6 asShortFloat fractionPart + 1.6 asShortFloat truncated + -1.6 asShortFloat fractionPart + -1.6 asShortFloat truncated - 1.0 asShortFloat fractionalPart - 0.5 asShortFloat fractionalPart - 0.25 asShortFloat fractionalPart - 3.14159 asShortFloat fractionalPart - 12345673.14159 asShortFloat fractionalPart - 123456731231231231.14159 asShortFloat fractionalPart + 1.0 asShortFloat fractionalPart + 0.5 asShortFloat fractionalPart + 0.25 asShortFloat fractionalPart + 3.14159 asShortFloat fractionalPart + 12345673.14159 asShortFloat fractionalPart + 123456731231231231.14159 asShortFloat fractionalPart " ! @@ -1476,46 +1477,46 @@ |val| -%{ +%{ float fVal; fVal = __shortFloatVal(self); #if defined(__i386__) && defined(__GNUC__) if (fVal < 0.0) { - fVal = ceilf(fVal - (float)0.5); + fVal = ceilf(fVal - (float)0.5); } else { - fVal = floorf(fVal + (float)0.5); + fVal = floorf(fVal + (float)0.5); } #else if (fVal < 0.0) { - fVal = (float)ceil((double)fVal - 0.5); + fVal = (float)ceil((double)fVal - 0.5); } else { - fVal = (float)floor((double)fVal + 0.5); + fVal = (float)floor((double)fVal + 0.5); } #endif /* * ST-80 (and X3J20) returns integer. */ if ((fVal >= (float)_MIN_INT) && (fVal <= (float)_MAX_INT)) { - RETURN ( __mkSmallInteger( (INT) fVal ) ); + RETURN ( __mkSmallInteger( (INT) fVal ) ); } __qMKSFLOAT(val, fVal); %}. ^ val asInteger " - 0.4 asShortFloat rounded - 0.5 asShortFloat rounded - 0.6 asShortFloat rounded - -0.4 asShortFloat rounded - -0.5 asShortFloat rounded - -0.6 asShortFloat rounded + 0.4 asShortFloat rounded + 0.5 asShortFloat rounded + 0.6 asShortFloat rounded + -0.4 asShortFloat rounded + -0.5 asShortFloat rounded + -0.6 asShortFloat rounded " ! roundedAsFloat "return the receiver rounded to the nearest integer as a float. - This is much like #rounded, but avoids a (possibly expensive) conversion + This is much like #rounded, but avoids a (possibly expensive) conversion of the result to an integer. It may be useful, if the result is to be further used in another float-operation." @@ -1526,15 +1527,15 @@ fVal = __shortFloatVal(self); #if defined(__i386__) && defined(__GNUC__) if (fVal < 0.0) { - fVal = ceilf(fVal - (float)0.5); + fVal = ceilf(fVal - (float)0.5); } else { - fVal = floorf(fVal + (float)0.5); + fVal = floorf(fVal + (float)0.5); } #else if (fVal < 0.0) { - fVal = (float)ceil((double)fVal - 0.5); + fVal = (float)ceil((double)fVal - 0.5); } else { - fVal = (float)floor((double)fVal + 0.5); + fVal = (float)floor((double)fVal + 0.5); } #endif __qMKSFLOAT(v, fVal); @@ -1542,19 +1543,19 @@ %} " - 0.4 asShortFloat rounded - 0.5 asShortFloat rounded - 0.6 asShortFloat rounded - -0.4 asShortFloat rounded - -0.5 asShortFloat rounded - -0.6 asShortFloat rounded + 0.4 asShortFloat rounded + 0.5 asShortFloat rounded + 0.6 asShortFloat rounded + -0.4 asShortFloat rounded + -0.5 asShortFloat rounded + -0.6 asShortFloat rounded - 0.4 asShortFloat roundedAsFloat - 0.5 asShortFloat roundedAsFloat - 0.6 asShortFloat roundedAsFloat - -0.4 asShortFloat roundedAsFloat - -0.5 asShortFloat roundedAsFloat - -0.6 asShortFloat roundedAsFloat + 0.4 asShortFloat roundedAsFloat + 0.5 asShortFloat roundedAsFloat + 0.6 asShortFloat roundedAsFloat + -0.4 asShortFloat roundedAsFloat + -0.5 asShortFloat roundedAsFloat + -0.6 asShortFloat roundedAsFloat " ! @@ -1563,46 +1564,46 @@ |val| -%{ +%{ float fVal; fVal = __shortFloatVal(self); #if defined(__i386__) && defined(__GNUC__) if (fVal < 0.0) { - fVal = ceilf(fVal); + fVal = ceilf(fVal); } else { - fVal = floorf(fVal); + fVal = floorf(fVal); } #else if (fVal < 0.0) { - fVal = (float)ceil((double)fVal); + fVal = (float)ceil((double)fVal); } else { - fVal = (float)floor((double)fVal); + fVal = (float)floor((double)fVal); } #endif /* * ST-80 (and X3J20) returns integer. */ if ((fVal >= (float)_MIN_INT) && (fVal <= (float)_MAX_INT)) { - RETURN ( __mkSmallInteger( (INT) fVal ) ); + RETURN ( __mkSmallInteger( (INT) fVal ) ); } __qMKSFLOAT(val, fVal); %}. ^ val asInteger " - 0.5 asShortFloat truncated - -0.5 asShortFloat truncated - 0.5 asShortFloat truncatedAsFloat - -0.5 asShortFloat truncatedAsFloat + 0.5 asShortFloat truncated + -0.5 asShortFloat truncated + 0.5 asShortFloat truncatedAsFloat + -0.5 asShortFloat truncatedAsFloat " ! truncatedAsFloat "return the receiver truncated towards zero as a float. - This is much like #truncated, but avoids a (possibly expensive) conversion + This is much like #truncated, but avoids a (possibly expensive) conversion of the result to an integer. - It may be useful, if the result is to be further used in another + It may be useful, if the result is to be further used in another float-operation." %{ /* NOCONTEXT */ @@ -1612,15 +1613,15 @@ fVal = __shortFloatVal(self); #if defined(__i386__) && defined(__GNUC__) if (fVal < 0.0) { - fVal = ceilf(fVal); + fVal = ceilf(fVal); } else { - fVal = floorf(fVal); + fVal = floorf(fVal); } #else if (fVal < 0.0) { - fVal = (float)ceil((double)fVal); + fVal = (float)ceil((double)fVal); } else { - fVal = (float)floor((double)fVal); + fVal = (float)floor((double)fVal); } #endif __qMKSFLOAT(v, fVal); @@ -1628,15 +1629,15 @@ %} " - 0.5 asShortFloat truncated - -0.5 asShortFloat truncated - 0.5 asShortFloat truncatedAsFloat - -0.5 asShortFloat truncatedAsFloat + 0.5 asShortFloat truncated + -0.5 asShortFloat truncated + 0.5 asShortFloat truncatedAsFloat + -0.5 asShortFloat truncatedAsFloat " ! ! !ShortFloat class methodsFor:'documentation'! version - ^ '$Header: /cvs/stx/stx/libbasic/ShortFloat.st,v 1.99 2009-09-14 22:00:18 cg Exp $' + ^ '$Header: /cvs/stx/stx/libbasic/ShortFloat.st,v 1.100 2009-09-16 17:08:24 cg Exp $' ! !