--- a/LongFloat.st Mon Jun 16 20:48:51 2003 +0200
+++ b/LongFloat.st Tue Jun 17 10:42:42 2003 +0200
@@ -1,5 +1,3 @@
-"
- COPYRIGHT (c) 1999 by eXept Software AG
All Rights Reserved
This software is furnished under a license and may be used
@@ -101,7 +99,6 @@
# define LONG_log logl
# define LONG_log10 log10l
# define LONG_pow powl
-# define LONG_isnan isnanl
# endif
#endif
@@ -158,9 +155,7 @@
!LongFloat class methodsFor:'documentation'!
-copyright
-"
- COPYRIGHT (c) 1999 by eXept Software AG
+1999 by eXept Software AG
All Rights Reserved
This software is furnished under a license and may be used
@@ -175,31 +170,53 @@
documentation
"
LongFloats represent rational numbers with limited precision.
- In ST/X, Float uses the underlying C-compilers double implementation,
- while LongFloats are mapped onto C-long doubles.
- Therefore instances of Float are usually represented by the 8-byte IEEE
- double precision float format (64 bits),
- while LongFloats use 10, 12 or 16 byte extended IEEE format (80, 96 or 128 bits).
+ They use the C-compilers 'long double' format, which is usually
+ the IEE extended float format.
+
+ In contrast to Floats (which use the C-compilers 64bit 'double' format),
+ LongFloats give you 80, 96 or 128 bits floats.
+ The actual number of bits depends on the underlying CPU
+ (thus, longFloat code is not quaranteed to be portable).
+
+ NO GUARANTY:
+ on systems which do not support 'long doubles', LongFloats are (silently)
+ represented as 'doubles'.
- But there is no guaranty:
- on systems which do not support long doubles, LongFloats are represented as Doubles.
+ Representation:
+ gcc-i386:
+ 80bit ext-precision IEE floats stored in in 96bits (12bytes);
+ 64 bit mantissa,
+ 16 bit exponent,
+ 19 decimal digits (approx)
- Linux:
- 80bit floats stored in 96 bits.
+ gcc-sparc:
+ 128bit ext-precision IEE floats stored in in 128bits (16bytes);
+ 64 bit mantissa,
+ 16 bit exponent,
+ 19 decimal digits (approx)
+
+ Mixed mode arithmetic:
+ longFloat op longFloat -> longFloat
+ longFloat op fix -> longFloat
+ longFloat op fraction -> longFloat
+ longFloat op integer -> longFloat
+ longFloat op shortFloat -> longFloat
+ longFloat op float -> longFloat
+ longFloat op complex -> complex
[author:]
- Claus Gittinger
+ Claus Gittinger
[see also:]
- Number
- Float ShortFloat Fraction FixedPoint Integer
+ Number
+ Float ShortFloat Fraction FixedPoint Integer Complex
+ FloatArray DoubleArray
"
! !
!LongFloat class methodsFor:'instance creation'!
-basicNew
- "return a new longFloat - here we return 0.0
+longFloat - here we return 0.0
- LongFloats are usually NOT created this way ...
Its implemented here to allow things like binary store & load
of longFloats. (but even this support will go away eventually, its not
@@ -215,8 +232,7 @@
%}
!
-fromFloat:aFloat
- "return a new longFloat, given a float value"
+rn a new longFloat, given a float value"
%{ /* NOCONTEXT */
OBJ newFloat;
@@ -249,7 +265,7 @@
"
!
-readFrom:aStringOrStream onError:exceptionBlock
+nError:exceptionBlock
"read a longFloat from a string"
|num|
@@ -270,8 +286,7 @@
!LongFloat class methodsFor:'constants'!
-pi
- "return the constant pi as LongFloat"
+t pi as LongFloat"
"the number of digits below is misleading:
as the compiler does not (yet) know about longFloats, the constant is initially
@@ -283,8 +298,7 @@
"Modified: 23.4.1996 / 09:26:31 / cg"
!
-unity
- "return the neutral element for multiplication (1.0) as LongFloat"
+ral element for multiplication (1.0) as LongFloat"
LongFloatOne isNil ifTrue:[
LongFloatOne := 1.0 asLongFloat.
@@ -294,8 +308,7 @@
"Modified: 23.4.1996 / 09:26:51 / cg"
!
-zero
- "return the neutral element for addition (0.0) as LongFloat"
+al element for addition (0.0) as LongFloat"
LongFloatZero isNil ifTrue:[
LongFloatZero := 0.0 asLongFloat
@@ -307,12 +320,9 @@
!LongFloat class methodsFor:'queries'!
-exponentCharacter
- ^ $q
!
-isBuiltInClass
- "return true if this class is known by the run-time-system.
+true if this class is known by the run-time-system.
Here, true is returned for myself, false for subclasses."
^ self == LongFloat
@@ -320,8 +330,7 @@
"Modified: 23.4.1996 / 16:00:23 / cg"
!
-isIEEEFormat
- "return true, if this machine represents floats in IEEE format.
+rue, if this machine represents floats in IEEE format.
Currently, no support is provided for non-ieee machines
to convert their floats into this (which is only relevant,
if such a machine wants to send floats as binary to some other
@@ -332,8 +341,7 @@
^ true "/ this may be a lie
!
-numBitsInExponent
- "answer the number of bits in the exponent
+wer the number of bits in the exponent
i386: This is an 80bit longfloat stored in 96 bits (upper 16 bits are unused),
where 15 bits are available in the exponent (i bit is ignored):
00000000 00000000 seeeeeee eeeeeeee immmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm
@@ -359,8 +367,7 @@
"
!
-numBitsInIntegerPart
- "answer the number of bits in the integer part of the mantissa
+answer the number of bits in the integer part of the mantissa
i386: This is an 80bit longfloat stored in 96 bits (upper 16 bits are unused),
where 1 bit is used for the integer part in the mantissa:
00000000 00000000 seeeeeee eeeeeeee immmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm
@@ -386,8 +393,7 @@
"
!
-numBitsInMantissa
- "answer the number of bits in the mantissa
+wer the number of bits in the mantissa
i386: This is an 80bit longfloat stored in 96 bits (upper 16 bits are unused),
where 1+63 bits are available in the mantissa:
00000000 00000000 seeeeeee eeeeeeee immmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm
@@ -416,8 +422,7 @@
"
!
-radix
- "answer the radix of a LongFloats exponent
+of a LongFloats exponent
This is an IEEE float, which is represented as binary"
^ 2 "must be careful here, whenever ST/X is used on VAX or a 370"
@@ -425,8 +430,7 @@
!LongFloat methodsFor:'arithmetic'!
-* aNumber
- "return the product of the receiver and the argument, aNumber"
+product of the receiver and the argument, aNumber"
%{ /* NOCONTEXT */
@@ -457,8 +461,7 @@
^ aNumber productFromLongFloat:self
!
-+ aNumber
- "return the sum of the receiver and the argument, aNumber"
+sum of the receiver and the argument, aNumber"
%{ /* NOCONTEXT */
@@ -489,8 +492,7 @@
^ aNumber sumFromLongFloat:self
!
-- aNumber
- "return the difference of the receiver and the argument, aNumber"
+difference of the receiver and the argument, aNumber"
%{ /* NOCONTEXT */
@@ -521,8 +523,7 @@
^ aNumber differenceFromLongFloat:self
!
-/ aNumber
- "return the quotient of the receiver and the argument, aNumber"
+quotient of the receiver and the argument, aNumber"
%{ /* NOCONTEXT */
@@ -570,8 +571,7 @@
^ aNumber quotientFromLongFloat:self
!
-negated
- "return myself negated"
+negated"
%{ /* NOCONTEXT */
OBJ newFloat;
@@ -582,8 +582,7 @@
%}.
!
-uncheckedDivide:aNumber
- "return the quotient of the receiver and the argument, aNumber.
+"return the quotient of the receiver and the argument, aNumber.
Do not check for divide by zero (return NaN or infinity).
This operation is provided for emulators of other languages/semantics,
where no exception is raised for these results (i.e. Java).
@@ -628,8 +627,7 @@
!LongFloat methodsFor:'coercing & converting'!
-asFloat
- "return a Float with same value as the receiver.
+t with same value as the receiver.
CAVEAT: should raise an error if the receiver exceeds the quadFloat range."
%{ /* NOCONTEXT */
@@ -646,8 +644,7 @@
"
!
-asInteger
- "return an integer with same value - might truncate"
+nteger with same value - might truncate"
%{ /* NOCONTEXT */
LONGFLOAT fVal;
@@ -665,14 +662,12 @@
"
!
-asLongFloat
- "return a LongFloat with same value as the receiver - thats me"
+LongFloat with same value as the receiver - thats me"
^ self
!
-asShortFloat
- "return a ShortFloat with same value as the receiver.
+ShortFloat with same value as the receiver.
CAVEAT: should raise an error if the receiver exceeds the float range."
%{ /* NOCONTEXT */
@@ -689,22 +684,19 @@
"
!
-coerce:aNumber
- "return aNumber converted into receivers type"
+aNumber converted into receivers type"
^ aNumber asLongFloat
!
-generality
- "return the generality value - see ArithmeticValue>>retry:coercing:"
+generality value - see ArithmeticValue>>retry:coercing:"
^ 90
! !
!LongFloat methodsFor:'comparing'!
-< aNumber
- "return true, if the argument is greater"
+, if the argument is greater"
%{ /* NOCONTEXT */
@@ -731,8 +723,7 @@
"
!
-<= aNumber
- "return true, if the argument is greater or equal"
+e, if the argument is greater or equal"
%{ /* NOCONTEXT */
@@ -754,8 +745,7 @@
^ self retry:#<= coercing:aNumber
!
-= aNumber
- "return true, if the argument represents the same numeric value
+, if the argument represents the same numeric value
as the receiver, false otherwise"
%{ /* NOCONTEXT */
@@ -778,8 +768,7 @@
^ aNumber equalFromLongFloat:self
!
-> aNumber
- "return true, if the argument is less"
+, if the argument is less"
%{ /* NOCONTEXT */
@@ -801,8 +790,7 @@
^ self retry:#> coercing:aNumber
!
->= aNumber
- "return true, if the argument is less or equal"
+e, if the argument is less or equal"
%{ /* NOCONTEXT */
@@ -824,8 +812,7 @@
^ self retry:#>= coercing:aNumber
!
-hash
- "return a number for hashing; redefined, since floats compare
+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."
@@ -849,8 +836,7 @@
"
!
-~= aNumber
- "return true, if the arguments value are not equal."
+e, if the arguments value are not equal."
%{ /* NOCONTEXT */
@@ -876,8 +862,7 @@
!LongFloat methodsFor:'mathematical functions'!
-arcCos
- "return the arccosine of myself (I am interpreted as radians).
+cosine of myself (I am interpreted as radians).
Raises an exception, if the receiver is not in -1..1"
%{ /* NOCONTEXT */
@@ -894,8 +879,8 @@
{
__threadErrno = 0;
rslt = LONG_acos(val);
-# ifdef LONG_isnan
- if (! LONG_isnan(rslt))
+# ifdef LINUX /* and maybe others */
+ if (! isnanl(rslt))
# endif
{
if (__threadErrno == 0) {
@@ -920,8 +905,7 @@
"
!
-arcSin
- "return the arcsine of myself (I am interpreted as radians).
+return the arcsine of myself (I am interpreted as radians).
Raises an exception, if the receiver is not in -1..1"
%{ /* NOCONTEXT */
@@ -938,8 +922,8 @@
{
__threadErrno = 0;
rslt = LONG_asin(val);
-# ifdef LONG_isnan
- if (! LONG_isnan(rslt))
+# ifdef LINUX /* and maybe others */
+ if (! isnanl(rslt))
# endif
{
if (__threadErrno == 0) {
@@ -975,14 +959,12 @@
__threadErrno = 0;
rslt = LONG_atan(__longFloatVal(self));
-# ifdef LONG_isnan
- if (! LONG_isnan(rslt))
+# ifdef LINUX /* and maybe others */
+ if (! isnanl(rslt))
# endif
- {
- if (__threadErrno == 0) {
- __qMKLFLOAT(newFloat, rslt);
- RETURN ( newFloat );
- }
+ if (__threadErrno == 0) {
+ __qMKLFLOAT(newFloat, rslt);
+ RETURN ( newFloat );
}
#endif
%}.
@@ -994,8 +976,7 @@
errorString:'bad receiver in arcTan'
!
-cos
- "return the cosine of myself interpreted as radians"
+"return the cosine of myself interpreted as radians"
%{ /* NOCONTEXT */
#if defined(LONG_cos)
@@ -1022,8 +1003,7 @@
errorString:'bad receiver in cos'
!
-exp
- "return e raised to the power of the receiver"
+"return e raised to the power of the receiver"
%{ /* NOCONTEXT */
#if defined(LONG_exp)
@@ -1050,8 +1030,7 @@
errorString:'bad receiver in exp'
!
-ln
- "return the natural logarithm of myself.
+"return the natural logarithm of myself.
Raises an exception, if the receiver is less or equal to zero."
%{ /* NOCONTEXT */
@@ -1068,8 +1047,8 @@
{
__threadErrno = 0;
rslt = LONG_log(val);
-# ifdef LONG_isnan
- if (! LONG_isnan(rslt))
+# ifdef LINUX /* and maybe others */
+ if (! isnanl(rslt))
# endif
{
if (__threadErrno == 0) {
@@ -1109,8 +1088,8 @@
{
__threadErrno = 0;
rslt = LONG_log10(val);
-# ifdef LONG_isnan
- if (! LONG_isnan(rslt))
+# ifdef LINUX /* and maybe others */
+ if (! isnanl(rslt))
# endif
{
if (__threadErrno == 0) {
@@ -1132,43 +1111,7 @@
errorString:'bad receiver in log10'
!
-raisedTo:aNumber
- "return self raised to the power of aNumber"
-
- |n|
-
- n := aNumber asFloat.
-%{
-#if defined(LONG_pow)
- LONGFLOAT rslt;
- OBJ newFloat;
-
- if (__isFloatLike(n)) {
- __threadErrno = 0;
- rslt = LONG_pow(__longFloatVal(self), __floatVal(n));
-# ifdef LONG_isnan
- if (! LONG_isnan(rslt))
-# endif
- {
- if (__threadErrno == 0) {
- __qMKLFLOAT(newFloat, rslt);
- RETURN ( newFloat );
- }
- }
- }
-#endif
-%}.
- "
- an invalid argument (not convertable to float ?)
- "
- ^ self class
- raise:#domainErrorSignal
- receiver:self
- selector:#raisedTo:
- arguments:(Array with:aNumber)
- errorString:'bad receiver/arg in raisedTo:'
-
- "Modified: / 16.11.2001 / 14:16:51 / cg"
+er in log10'
!
sin
@@ -1217,8 +1160,8 @@
{
__threadErrno = 0;
rslt = LONG_sqrt(val);
-# ifdef LONG_isnan
- if (! LONG_isnan(rslt))
+# ifdef LINUX /* and maybe others */
+ if (! isnanl(rslt))
# endif
{
if (__threadErrno == 0) {
@@ -1244,565 +1187,71 @@
"Modified: / 16.11.2001 / 14:14:43 / cg"
!
-tan
- "return the tangens of myself interpreted as radians"
-
-%{ /* NOCONTEXT */
-#if defined(LONG_tan)
-
- LONGFLOAT rslt;
- OBJ newFloat;
-
- __threadErrno = 0;
- rslt = LONG_tan(__longFloatVal(self));
-# ifdef LINUX /* and maybe others */
- if (! isnan(rslt))
-# endif
- if (__threadErrno == 0) {
- __qMKLFLOAT(newFloat, rslt);
- RETURN ( newFloat );
- }
-#endif
-%}.
- ^ self class
- raise:#domainErrorSignal
- receiver:self
- selector:#tan
- arguments:#()
- errorString:'bad receiver in tan'
+cg"
! !
!LongFloat methodsFor:'printing & storing'!
-printString
- "return a printed representation of the receiver
- LimitedPrecisonReal and its subclasses use #printString instead of
- #printOn: as basic print mechanism."
-
-%{ /* 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__
-
- if (sizeof(LONGFLOAT) == sizeof(double)) {
-#ifdef SYSV
- sprintf(buffer, "%.6lg", __longFloatVal(self));
-#else
- sprintf(buffer, "%.6G", __longFloatVal(self));
-#endif
- } else {
- sprintf(buffer, "%.6LG", __longFloatVal(self));
- }
-
- __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') || (*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.
+ring'
!
-printfPrintString:formatString
- "non-portable: return a printed representation of the receiver
- as specified by formatString, which is defined by printf.
- If you use this, be aware, that specifying long doubles differs on
- systems; on Linux/gnuc machines you have to give something like %LF/%LG.
- Also, the resulting string may not be longer than 255 bytes -
- since thats the (static) size of the buffer.
- This method is NONSTANDARD and may be removed without notice."
-
-%{ /* STACK: 400 */
- char buffer[256];
- OBJ s;
-
- if (__isString(formatString)) {
- sprintf(buffer, __stringVal(formatString), __longFloatVal(self));
-
- s = __MKSTRING(buffer COMMA_SND);
- if (s != nil) {
- RETURN (s);
- }
- }
-%}.
- self primitiveFailed
-
- "
- Float pi asLongFloat printfPrintString:'%%LG -> %LG'
- Float pi asLongFloat printfPrintString:'%%LF -> %LF'
- Float pi asLongFloat printfPrintString:'%%7.5LG -> %7.5LG'
- Float pi asLongFloat printfPrintString:'%%7.5LF -> %7.5LF'
- "
+ise.
! !
!LongFloat methodsFor:'special access'!
-exponent
- "extract a normalized floats exponent.
- The returned value depends on the float-representation of
- the underlying machine and is therefore highly unportable.
- This is not for general use.
- This assumes that the mantissa is normalized to
- 0.5 .. 1.0 and the floats value is mantissa * 2^exp"
-
-%{ /* NOCONTEXT */
-
-#if defined(i386) && defined(__GNUC__)
- LONGFLOAT LONG_frexp();
- INT exp;
-
- __threadErrno = 0;
- LONG_frexp( __longFloatVal(self), &exp);
- if (__threadErrno == 0) {
- RETURN (__MKSMALLINT(exp));
- }
-#endif
-%}.
- ^ self primitiveFailed
-
- "
- 4.0 asLongFloat exponent
- 2.0 asLongFloat exponent
- 1.0 asLongFloat exponent
- 0.5 asLongFloat exponent
- 0.25 asLongFloat exponent
- 0.00000011111 asLongFloat exponent
- "
+cess'
! !
!LongFloat methodsFor:'testing'!
-isFinite
- "return true, if the receiver is a finite float
- i.e. not NaN and not infinite."
-
-%{ /* NOCONTEXT */
-
-#ifdef NO_ISFINITE_FOR_LONGFLOAT
- double dV = (double) __longFloatVal(self);
-
- /*
- * notice: on machines which do not provide
- * a finite() macro or function (WIN32),
- * this may always ret true here ...
- */
- if (finite(dV)) { RETURN (true); }
-#else
- LONGFLOAT lV = __longFloatVal(self);
- if (finite(lV)) { RETURN (true); }
-#endif
-%}.
- ^false
-
- "
- 1.0 asLongFloat isFinite
- (0.0 asLongFloat uncheckedDivide: 0.0) isFinite
- (1.0 asLongFloat uncheckedDivide: 0.0) isFinite
- (-1.0 asLongFloat uncheckedDivide: 0.0) isFinite
- "
+ting'
!
-isNaN
- "return true, if the receiver is an invalid float (NaN - not a number).
- These are not created by ST/X float operations (they raise an exception);
- however, inline C-code could produce them ..."
-
-%{ /* NOCONTEXT */
-
-#ifdef NO_ISNAN_FOR_LONGFLOAT
- double dV = (double)(__longFloatVal(self));
-
- /*
- * notice: on machines which do not provide
- * a finite() macro or function (WIN32),
- * this may always ret false here ...
- */
- if (isnan(dV)) { RETURN (true); }
-#else
- LONGFLOAT lV = __longFloatVal(self);
- if (isnan(lV)) { RETURN (true); }
-#endif
-
-#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 IS_NAN
- if (IS_NAN(dV)) { RETURN (true); }
- RETURN (false);
-#endif
-
-#ifdef IS_QNAN
- if (IS_QNAN(dV)) { RETURN (true); }
- RETURN (false);
-#endif
-
-#ifdef FLT_SNAN
- if (dV == FLT_SNAN) { RETURN (true); }
- RETURN (false);
-#endif
-
-#ifdef FLT_QNAN
- if (dV == FLT_QNAN) { RETURN (true); }
- RETURN (false);
-#endif
-
-#ifdef _SNANF
- if (dV == _SNAN) { RETURN (true); }
- RETURN (false);
-#endif
-
-#ifdef _QNANF
- if (dV == _QNAN) { RETURN (true); }
- RETURN (false);
-#endif
-
-#ifdef IsPosNAN
- if IsPosNAN(dV) { RETURN (true); }
- RETURN (false);
-#endif
-
-#ifdef IsNegNAN
- if IsNegNAN(dV) { RETURN (true); }
- RETURN (false);
-#endif
-
-#ifdef NAN
- if (dV == NAN) { RETURN (true); }
- RETURN (false);
-#endif
-
-#ifdef NaN
- if (NaN(dV)) { RETURN (true); }
- RETURN (false);
-#endif
-
-#endif /* 0 */
-%}.
- ^ false
-
- "
- 1.0 asLongFloat isNaN
- (0.0 asLongFloat uncheckedDivide: 0.0) isNaN
- "
+"
!
-negative
- "return true if the receiver is less than zero"
+"
+!
-%{ /* NOCONTEXT */
-
- RETURN ( (__longFloatVal(self) < 0.0) ? true : false );
%}.
!
-numberOfBits
- "return the size (in bits) of the real;
- typically, 80 or 96 is returned here,
- but who knows ..."
-
-%{ /* NOCONTEXT */
-
- RETURN (__MKSMALLINT (sizeof(LONGFLOAT) * 8));
-%}
-
- "
- LongFloat basicNew numberOfBits
- 1.2 asLongFloat numberOfBits
- 1.2 asShortFloat numberOfBits
- 1.2 numberOfBits
- "
+"
!
-positive
- "return true if the receiver is greater or equal to zero"
-
-%{ /* NOCONTEXT */
-
- RETURN ( (__longFloatVal(self) >= 0.0) ? true : false );
-%}
-!
-
-strictlyPositive
- "return true if the receiver is greater than zero"
-
-%{ /* NOCONTEXT */
-
- RETURN ( (__longFloatVal(self) > 0.0) ? true : false );
+;
%}
! !
!LongFloat methodsFor:'truncation & rounding'!
-ceiling
- "return the smallest integer which is greater or equal to the receiver."
-
- |val|
-
-%{
-#if defined(LONG_ceil)
- LONGFLOAT lVal;
-
- lVal = LONG_ceil(__longFloatVal(self));
- if ((lVal >= (LONGFLOAT)_MIN_INT) && (lVal <= (LONGFLOAT)_MAX_INT)) {
- RETURN ( __MKSMALLINT( (INT) lVal ) );
- }
- __qMKLFLOAT(val, lVal);
-#endif
-%}.
- val notNil ifTrue:[
- ^ val asInteger
- ].
- ^ super ceiling.
-
- "
- 0.5 asLongFloat ceiling
- -0.5 asLongFloat ceiling
- "
+ding'
!
-ceilingAsFloat
- "return the smallest integer-valued float greater or equal to the receiver.
- 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."
-
-%{ /* NOCONTEXT */
-#if defined(LONG_ceil)
- LONGFLOAT lVal;
- OBJ v;
-
- lVal = LONG_ceil(__longFloatVal(self));
- __qMKLFLOAT(v, lVal);
- RETURN (v);
-#endif
-%}.
- ^ super ceilingAsFloat
-
- "
- 0.5 asLongFloat ceilingAsFloat
- -0.5 asLongFloat ceilingAsFloat
- -1.5 asLongFloat ceilingAsFloat
- "
+"
!
-floor
- "return the integer nearest the receiver towards negative infinity."
-
- |val|
-
-%{
-#if defined(LONG_floor)
- LONGFLOAT lVal;
-
- lVal = LONG_floor(__longFloatVal(self));
- if ((lVal >= (LONGFLOAT)_MIN_INT) && (lVal <= (LONGFLOAT)_MAX_INT)) {
- RETURN ( __MKSMALLINT( (INT) lVal ) );
- }
- __qMKLFLOAT(val, lVal);
-#endif
-%}.
- val notNil ifTrue:[
- ^ val asInteger
- ].
- ^ super floor.
-
- "
- 0.5 asLongFloat floor
- -0.5 asLongFloat floor
- "
-!
-
-floorAsFloat
- "return the float which represents the next lower
- integer nearest the receiver towards negative infinity.
- Much like floor, but returns a float result - useful if the result
- will be used in another float operation, to avoid costy int-conversion."
-
-%{ /* NOCONTEXT */
-#if defined(LONG_floor)
- LONGFLOAT lVal;
- OBJ v;
-
- lVal = LONG_floor(__longFloatVal(self));
- __qMKLFLOAT(v, lVal);
- RETURN (v);
-#endif
-%}.
- ^ super floorAsFloat
-
- "
- 0.5 asLongFloat floorAsFloat
- -0.5 asLongFloat floorAsFloat
- -1.5 asLongFloat floorAsFloat
- "
+"
!
-rounded
- "return the receiver rounded to the nearest integer"
-
-%{ /* NOCONTEXT */
-#if defined(LONG_ceil) && defined(LONG_floor)
- LONGFLOAT lVal;
- OBJ v;
-
- lVal = __longFloatVal(self);
- if (lVal < 0.0) {
- lVal = LONG_ceil(lVal - (LONGFLOAT)0.5);
- } else {
- lVal = LONG_floor(lVal + (LONGFLOAT)0.5);
- }
- /*
- * ST-80 (and X3J20) returns integer.
- */
- if ((lVal >= (LONGFLOAT)_MIN_INT) && (lVal <= (LONGFLOAT)_MAX_INT)) {
- RETURN ( __MKSMALLINT( (INT) lVal ) );
- }
- __qMKLFLOAT(v, lVal);
- RETURN (v);
-#endif
-%}.
- ^ super rounded
-
- "
- 0.4 asLongFloat rounded
- 0.5 asLongFloat rounded
- 0.6 asLongFloat rounded
- -0.4 asLongFloat rounded
- -0.5 asLongFloat rounded
- -0.6 asLongFloat rounded
- "
+"
!
-roundedAsFloat
- "return the receiver rounded to the nearest integer as a float.
- 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."
-
-%{ /* NOCONTEXT */
-#if defined(LONG_ceil) && defined(LONG_floor)
- LONGFLOAT lVal;
- OBJ v;
-
- lVal = __longFloatVal(self);
- if (lVal < 0.0) {
- lVal = LONG_ceil(lVal - (LONGFLOAT)0.5);
- } else {
- lVal = LONG_floor(lVal + (LONGFLOAT)0.5);
- }
- __qMKLFLOAT(v, lVal);
- RETURN (v);
-#endif
-%}.
- ^ super roundedAsFloat
+"
!
-truncated
- "return the receiver truncated towards zero as an integer"
-
- |val|
-
-%{
-#if defined(LONG_ceil) && defined(LONG_floor)
- LONGFLOAT lVal;
-
- lVal = __longFloatVal(self);
- if (lVal < 0.0) {
- lVal = LONG_ceil(lVal);
- } else {
- lVal = LONG_floor(lVal);
- }
-
- /*
- * ST-80 (and X3J20) returns integer.
- */
- if ((lVal >= (LONGFLOAT)_MIN_INT) && (lVal <= (LONGFLOAT)_MAX_INT)) {
- RETURN ( __MKSMALLINT( (INT) lVal ) );
- }
- __qMKLFLOAT(val, lVal);
-#endif
-%}.
- val notNil ifTrue:[
- ^ val asInteger
- ].
- ^ super truncated
-
- "
- 0.5 asLongFloat truncated
- -0.5 asLongFloat truncated
- 0.5 asLongFloat truncatedAsFloat
- -0.5 asLongFloat truncatedAsFloat
- "
+"
!
-truncatedAsFloat
- "return the receiver truncated towards zero as a float.
- 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
- float-operation."
-
-%{ /* NOCONTEXT */
-#if defined(LONG_ceil) && defined(LONG_floor)
- LONGFLOAT lVal;
- OBJ v;
+loat
+!
- lVal = __longFloatVal(self);
- if (lVal < 0.0) {
- lVal = LONG_ceil(lVal);
- } else {
- lVal = LONG_floor(lVal);
- }
- __qMKLFLOAT(v, lVal);
- RETURN (v);
-#endif
-%}.
- ^ super truncatedAsFloat
-
- "
- 0.5 truncated
- -0.5 truncated
- 0.5 truncatedAsFloat
- -0.5 truncatedAsFloat
- "
+"
! !
!LongFloat class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/LongFloat.st,v 1.25 2003-06-16 15:27:44 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/LongFloat.st,v 1.26 2003-06-17 08:42:42 cg Exp $'
! !