# HG changeset patch # User Claus Gittinger # Date 926341936 -7200 # Node ID 6d83608a758480004b2e9d6d6bb0ae104accbc22 # Parent 59da946fb307f4dcda4c8fc8ae7e5e8195c2cff7 initial - not yet tested/released diff -r 59da946fb307 -r 6d83608a7584 LongFloat.st --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LongFloat.st Mon May 10 15:12:16 1999 +0200 @@ -0,0 +1,940 @@ +" + COPYRIGHT (c) 1999 by eXept Software AG + 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:#LongFloat + instanceVariableNames:'' + classVariableNames:'' + poolDictionaries:'' + category:'Magnitude-Numbers' +! + +!LongFloat primitiveDefinitions! +%{ + +#include + +#ifndef __OPTIMIZE__ +# define __OPTIMIZE__ +#endif +#include + +/* + * on some systems errno is a macro ... check for it here + */ +#ifndef errno + extern errno; +#endif + +#if defined (_AIX) +# include +#endif +#if defined(IRIX) +# include +#endif +#if defined(LINUX) +# include +#endif +#if defined(solaris) || defined(sunos) +# include +#endif + +#ifdef WIN32 +/* + * no finite(x) ? + * no isnan(x) ? + */ +# ifndef finite +# define finite(x) 1 +# endif +# ifndef isnan +# define isnan(x) 0 +# endif +#endif + +#ifdef realIX +/* + * no finite(x) + */ +# ifndef finite +# define finite(x) 1 +# endif +#endif + +#ifdef WIN32 +# define LONGFLOAT long double +#endif + +#ifndef LONGFLOAT +# define LONGFLOAT double +#endif + +#ifndef __qMKLFLOAT +# define __qMKLFLOAT(__newFloat__, __fVal__) \ + { \ + __qNew(__newFloat__ , 10); \ + if (__newFloat__) { \ + __qClass(__newFloat__) = @global(LongFloat); \ + ((long double *)(__newFloat->i_instvars))[0] = __fVal__; \ + } \ + } +%} +! ! + +!LongFloat class methodsFor:'documentation'! + +copyright +" + COPYRIGHT (c) 1999 by eXept Software AG + 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 +" + 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 IEE + double precision float format (64 bits), while LongFloats use 10byte extended IEE format + (80 bits). + But there is no guaranty - on systems which do not support long doubles, + LongFloats are represented as Doubles. + + [author:] + Claus Gittinger + + [see also:] + Number + Float ShortFloat Fraction FixedPoint Integer +" + +! ! + +!LongFloat class methodsFor:'instance creation'! + +basicNew + "return a new 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 + a good idea to store the bits of a float - the reader might have a + totally different representation - so floats will eventually be + binary stored in a device independent format." + +%{ /* NOCONTEXT */ + OBJ newFloat; + + __qMKLFLOAT(newFloat, 0.0); /* OBJECT ALLOCATION */ + RETURN (newFloat); +%} +! + +readFrom:aStringOrStream onError:exceptionBlock + "read a longFloat from a string" + + |num| + + num := super readFrom:aStringOrStream onError:nil. + num isNil ifTrue:[ + ^ exceptionBlock value + ]. + ^ num asLongFloat + + " + LongFloat readFrom:'0.1' + LongFloat readFrom:'0' + " + + "Modified: / 7.1.1998 / 16:17:59 / cg" +! ! + +!LongFloat class methodsFor:'constants'! + +pi + "return the constant pi as LongFloat" + + ^ 3.14159 asLongFloat + + "Modified: 23.4.1996 / 09:26:31 / cg" +! + +unity + "return the neutral element for multiplication (1.0) as LongFloat" + + ^ 1.0 asLongFloat + + "Modified: 23.4.1996 / 09:26:51 / cg" +! + +zero + "return the neutral element for addition (0.0) as LongFloat" + + ^ 0.0 asLongFloat + + "Modified: 23.4.1996 / 09:26:45 / cg" +! ! + +!LongFloat class methodsFor:'queries'! + +isBuiltInClass + "return true if this class is known by the run-time-system. + Here, true is returned for myself, false for subclasses." + + ^ self == LongFloat + + "Modified: 23.4.1996 / 16:00:23 / cg" +! + +isIEEEFormat + "return true, 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 + machine). + Machines with non-IEEE format are VAXed and IBM370-type systems + (among others). Today, most systems use IEEE format floats." + + ^ true "/ this may be a lie +! ! + +!LongFloat methodsFor:'arithmetic'! + +* aNumber + "return the product of the receiver and the argument, aNumber" + +%{ /* NOCONTEXT */ + + OBJ newFloat; + LONGFLOAT result; + + if (__isSmallInteger(aNumber)) { + result = __longFloatVal(self) * (LONGFLOAT)(__intVal(aNumber)); +retResult: + __qMKLFLOAT(newFloat, result); + RETURN ( newFloat ); + } else if (__isLongFloat(aNumber)) { + result = __longFloatVal(self) * __longFloatVal(aNumber); + goto retResult; + } else if (__isFloatLike(aNumber)) { + result = __longFloatVal(self) * (LONGFLOAT)(__floatVal(aNumber)); + goto retResult; + } else if (__isShortFloat(aNumber)) { + result = __longFloatVal(self) * (LONGFLOAT)(__shortFloatVal(aNumber)); + goto retResult; + } +%}. + ^ aNumber productFromLongFloat:self +! + ++ aNumber + "return the sum of the receiver and the argument, aNumber" + +%{ /* NOCONTEXT */ + + OBJ newFloat; + LONGFLOAT result; + + if (__isSmallInteger(aNumber)) { + result = __longFloatVal(self) + (LONGFLOAT)(__intVal(aNumber)); +retResult: + __qMKLFLOAT(newFloat, result); + RETURN ( newFloat ); + } else if (__isLongFloat(aNumber)) { + result = __longFloatVal(self) + __longFloatVal(aNumber); + goto retResult; + } else if (__isShortFloat(aNumber)) { + result = __longFloatVal(self) + (LONGFLOAT)(__shortFloatVal(aNumber)); + goto retResult; + } else if (__isFloatLike(aNumber)) { + result = __longFloatVal(self) + (LONGFLOAT)(__floatVal(aNumber)); + goto retResult; + } +%}. + ^ aNumber sumFromLongFloat:self +! + +- aNumber + "return the difference of the receiver and the argument, aNumber" + +%{ /* NOCONTEXT */ + + OBJ newFloat; + LONGFLOAT result; + + if (__isSmallInteger(aNumber)) { + result = __longFloatVal(self) - (LONGFLOAT)(__intVal(aNumber)); +retResult: + __qMKLFLOAT(newFloat, result); + RETURN ( newFloat ); + } else if (__isLongFloat(aNumber)) { + result = __longFloatVal(self) - __longFloatVal(aNumber); + goto retResult; + } else if (__isShortFloat(aNumber)) { + result = __longFloatVal(self) - (LONGFLOAT)(__shortFloatVal(aNumber)); + goto retResult; + } else if (__isFloatLike(aNumber)) { + result = __longFloatVal(self) - (LONGFLOAT)(__floatVal(aNumber)); + goto retResult; + } +%}. + ^ aNumber differenceFromLongFloat:self +! + +/ aNumber + "return the quotient of the receiver and the argument, aNumber" + +%{ /* NOCONTEXT */ + + OBJ newFloat; + LONGFLOAT result, val; + + if (__isSmallInteger(aNumber)) { + if (aNumber != __MKSMALLINT(0)) { + result = __longFloatVal(self) / (LONGFLOAT)(__intVal(aNumber)); +retResult: + __qMKLFLOAT(newFloat, result); + RETURN ( newFloat ); + } + } else if (__isLongFloat(aNumber)) { + val = __longFloatVal(aNumber); + if (val != 0.0) { + result = __longFloatVal(self) / val; + goto retResult; + } + } else if (__isFloatLike(aNumber)) { + val = (LONGFLOAT)(__floatVal(aNumber)); + if (val != 0.0) { + result = __longFloatVal(self) / dVal; + goto retResult; + } + } else if (__isShortFloat(aNumber)) { + val = (LONGFLOAT)(__shortFloatVal(aNumber)); + if (val != 0.0) { + result = __longFloatVal(self) / dVal; + goto retResult; + } + } +%}. + ((aNumber == 0) or:[aNumber = 0.0]) ifTrue:[ + " + No, you shalt not divide by zero + " + ^ DivisionByZeroSignal raise. + ]. + ^ aNumber quotientFromLongFloat:self +! + +negated + "return myself negated" + +%{ /* NOCONTEXT */ + OBJ newFloat; + LONGFLOAT rslt = - __longFloatVal(self); + + __qMKKFLOAT(newFloat, rslt); + RETURN ( newFloat ); +%} + +! + +uncheckedDivide:aNumber + "return the quotient of the receiver and the argument, aNumber + Do not check for divide by zero (return NaN or infinity)" + +%{ /* NOCONTEXT */ + + OBJ newFloat; + LONGFLOAT result, val; + + if (__isSmallInteger(aNumber)) { + result = __longFloatVal(self) / (LONGFLOAT)(__intVal(aNumber)); +retResult: + __qMKLFLOAT(newFloat, result); + RETURN ( newFloat ); + } else if (__isLongFloat(aNumber)) { + result = __longFloatVal(self) / __longFloatVal(aNumber); + goto retResult; + } else if (__isFloatLike(aNumber)) { + val = (LONGFLOAT)(__floatVal(aNumber)); + result = __longFloatVal(self) / val; + goto retResult; + } else if (__isShortFloat(aNumber)) { + val = (LONGFLOAT)(__shortFloatVal(aNumber)); + result = __longFloatVal(self) / val; + goto retResult; + } +%}. + ^ aNumber quotientFromLongFloat:self + + " + 0.0 asLongFloat uncheckedDivide:0 + 1.0 asLongFloat uncheckedDivide:0.0 + " + +! ! + +!LongFloat methodsFor:'coercion and converting'! + +asFloat + "return a Float with same value as the receiver" + +%{ /* NOCONTEXT */ + + OBJ newFloat; + double dVal = (double)__longFloatVal(self); + + __qMKFLOAT(newFloat, dVal); + RETURN ( newFloat ); +%} + + " + 1.0 asLongFloat + " +! + +asShortFloat + "return a ShortFloat with same value as the receiver" + +%{ /* NOCONTEXT */ + + OBJ newFloat; + float fVal = (float)__longFloatVal(self); + + __qMKSFLOAT(newFloat, fVal); + RETURN ( newFloat ); +%} + + " + 1.0 asLongFloat asShortFloat + " +! + +asInteger + "return an integer with same value - might truncate" + +%{ /* NOCONTEXT */ + LONGFLOAT fVal; + + fVal = __longFloatVal(self); + if ((fVal >= (LONGFLOAT)_MIN_INT) && (fVal <= (LONGFLOAT)_MAX_INT)) { + RETURN ( __MKSMALLINT( (INT)fVal) ); + } +%}. + ^ super asInteger + + " + 12345.0 asLongFloat asInteger + 1e15 asLongFloat asInteger + " +! + +asLongFloat + "return a LongFloat with same value as the receiver - thats me" + + ^ self +! + +generality + "return the generality value - see ArithmeticValue>>retry:coercing:" + + ^ 90 +! ! + +!LongFloat methodsFor:'comparing'! + +< aNumber + "return true, if the argument is greater" + +%{ /* NOCONTEXT */ + + if (__isSmallInteger(aNumber)) { + RETURN ( (__longFloatVal(self) < (LONGFLOAT)(__intVal(aNumber))) ? true : false ); + } + if (__isLongFloat(aNumber)) { + RETURN ( (__longFloatVal(self) < __longFloatVal(aNumber)) ? true : false ); + } + if (__isFloatLike(aNumber)) { + RETURN ( (__longFloatVal(self) < (LONGFLOAT)(__floatVal(aNumber))) ? true : false ); + } + if (__isShortFloat(aNumber)) { + RETURN ( (__longFloatVal(self) < (LONGFLOAT)(__shortFloatVal(aNumber))) ? true : false ); + } +%}. + ^ aNumber lessFromLongFloat:self + + " + 1.0 asLongFloat > (1/3) + 1.0 asLongFloat > (1/3) asLongFloat + " +! + +<= aNumber + "return true, if the argument is greater or equal" + +%{ /* NOCONTEXT */ + + if (__isSmallInteger(aNumber)) { + RETURN ( (__longFloatVal(self) <= (LONGFLOAT)(__intVal(aNumber))) ? true : false ); + } + if (__isLongFloat(aNumber)) { + RETURN ( (__longFloatVal(self) <= __longFloatVal(aNumber)) ? true : false ); + } + if (__isFloatLike(aNumber)) { + RETURN ( (__longFloatVal(self) <= (LONGFLOAT)(__floatVal(aNumber))) ? true : false ); + } + if (__isShortFloat(aNumber)) { + RETURN ( (__longFloatVal(self) <= (LONGFLOAT)(__shortFloatVal(aNumber))) ? true : false ); + } +%}. + ^ self retry:#<= coercing:aNumber + +! + += aNumber + "return true, if the arguments value are equal by value" + +%{ /* NOCONTEXT */ + + if (__isSmallInteger(aNumber)) { + RETURN ( (__longFloatVal(self) == (LONGFLOAT)(__intVal(aNumber))) ? true : false ); + } + if (__isLongFloat(aNumber)) { + RETURN ( (__longFloatVal(self) == __longFloatVal(aNumber)) ? true : false ); + } + if (__isFloatLike(aNumber)) { + RETURN ( (__longFloatVal(self) == (LONGFLOAT)(__floatVal(aNumber))) ? true : false ); + } + if (__isShortFloat(aNumber)) { + RETURN ( (__longFloatVal(self) == (LONGFLOAT)(__shortFloatVal(aNumber))) ? true : false ); + } +%}. + ^ self retry:#= coercing:aNumber + +! + +> aNumber + "return true, if the argument is less" + +%{ /* NOCONTEXT */ + + if (__isSmallInteger(aNumber)) { + RETURN ( (__longFloatVal(self) > (LONGFLOAT)(__intVal(aNumber))) ? true : false ); + } + if (__isLongFloat(aNumber)) { + RETURN ( (__longFloatVal(self) > __longFloatVal(aNumber)) ? true : false ); + } + if (__isFloatLike(aNumber)) { + RETURN ( (__longFloatVal(self) > (LONGFLOAT)(__floatVal(aNumber))) ? true : false ); + } + if (__isShortFloat(aNumber)) { + RETURN ( (__longFloatVal(self) > (LONGFLOAT)(__shortFloatVal(aNumber))) ? true : false ); + } +%}. + ^ self retry:#> coercing:aNumber +! + +>= aNumber + "return true, if the argument is less or equal" + +%{ /* NOCONTEXT */ + + if (__isSmallInteger(aNumber)) { + RETURN ( (__longFloatVal(self) >= (LONGFLOAT)(__intVal(aNumber))) ? true : false ); + } + if (__isLongFloat(aNumber)) { + RETURN ( (__longFloatVal(self) >= __longFloatVal(aNumber)) ? true : false ); + } + if (__isFloatLike(aNumber)) { + RETURN ( (__longFloatVal(self) >= (LONGFLOAT)(__floatVal(aNumber))) ? true : false ); + } + if (__isShortFloat(aNumber)) { + RETURN ( (__longFloatVal(self) >= (LONGFLOAT)(__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 asLongFloat hash + 1.0 hash + 1.0 asLongFloat hash + " +! + +~= aNumber + "return true, if the arguments value are not equal" + +%{ /* NOCONTEXT */ + + if (__isSmallInteger(aNumber)) { + RETURN ( (__longFloatVal(self) != (LONGFLOAT)(__intVal(aNumber))) ? true : false ); + } + if (__isLongFloat(aNumber)) { + RETURN ( (__longFloatVal(self) != __longFloatVal(aNumber)) ? true : false ); + } + if (__isFloatLike(aNumber)) { + RETURN ( (__longFloatVal(self) != (LONGFLOAT)(__floatVal(aNumber))) ? true : false ); + } + if (__isShortFloat(aNumber)) { + RETURN ( (__longFloatVal(self) != (LONGFLOAT)(__shortFloatVal(aNumber))) ? true : false ); + } +%}. + ^ self retry:#~= coercing:aNumber + +! ! + +!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__ + + 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')) 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. +! ! + +!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 0 + double frexp(); + double frac; + INT exp; + + errno = 0; + frac = frexp( (double)(__shortFloatVal(self)), &exp); + if (errno == 0) { + RETURN (__MKSMALLINT(exp)); + } +#endif +%}. + ^ self primitiveFailed + + " + 1.0 asLongFloat exponent + 1.0 asLongFloat exponent + 0.5 asLongFloat exponent + 0.25 asLongFloat exponent + 0.00000011111 asLongFloat exponent + " +! + +mantissa + "extract a normalized floats mantissa. + 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 0 + double frexp(); + double frac; + INT exp; + + errno = 0; + frac = frexp( (double)(__shortFloatVal(self)), &exp); + if (errno == 0) { + RETURN (__MKFLOAT(frac)); + } +#endif +%}. + ^ self primitiveFailed + + " + 1.0 asLongFloat exponent + 1.0 asLongFloat mantissa + + 0.5 asLongFloat exponent + 0.5 asLongFloat mantissa + + 0.25 asLongFloat exponent + 0.25 asLongFloat mantissa + + 0.00000011111 asLongFloat exponent + 0.00000011111 asLongFloat mantissa + " +! ! + +!LongFloat methodsFor:'testing'! + +isFinite + "return true, if the receiver is a finite float + i.e. not NaN and not infinite." + +%{ /* NOCONTEXT */ + + double dV = (double) __longFloatVal(self); + + /* + * notice: on machines which do not provide + * a finite() macro or function (WIN32), + * this may always return true here ... + */ + if (finite(dV)) { RETURN (true); } +%}. + ^false + + " + 1.0 asLongFloat isFinite + (0.0 asLongFloat uncheckedDivide: 0.0) isFinite + (1.0 asLongFloat uncheckedDivide: 0.0) isFinite + " +! + +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 */ + + double dV = (double)(__longFloatVal(self)); + + /* + * notice: on machines which do not provide + * a finite() macro or function (WIN32), + * this may always return false here ... + */ + if (isnan(dV)) { RETURN (true); } + +#if 0 /* Currently all our systems support isnan() + * If not, you have to fix librun/jinterpret.c also. + */ + + /* + * sigh - every vendor is playing its own game here ... + * Q: what are standards worth, anyway ? + */ +#ifdef 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 ); +%} +! + +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 and rounding'! + +floor + "return the integer nearest the receiver towards negative infinity." + + |val| + + ^ val asInteger + + " + 0.5 asLongFloat floor + -0.5 asLongFloat floor + " +! + +fractionPart + "extract the after-decimal fraction part. + the floats value is + float truncated + float fractionalPart" + +%{ /* NOCONTEXT */ +#if 0 + double modf(); + double frac, trunc; + + errno = 0; + frac = modf((double)(__shortFloatVal(self)), &trunc); + if (errno == 0) { + RETURN (__MKSFLOAT(frac)); + } +#endif +%}. + ^ self primitiveFailed + + " + 1.0 asLongFloat fractionalPart + 0.5 asLongFloat fractionalPart + 0.25 asLongFloat fractionalPart + 3.14159 asLongFloat fractionalPart + 12345673.14159 asLongFloat fractionalPart + 123456731231231231.14159 asLongFloat fractionalPart + " + +! ! + +!LongFloat class methodsFor:'documentation'! + +version + ^ '$Header: /cvs/stx/stx/libbasic/LongFloat.st,v 1.1 1999-05-10 13:12:16 cg Exp $' +! ! +