|
Class: LargeFloat
Object
|
+--Magnitude
|
+--ArithmeticValue
|
+--Number
|
+--LimitedPrecisionReal
|
+--LargeFloat
- Package:
- stx:libbasic2
- Category:
- Magnitude-Numbers
- Version:
- rev:
1.55
date: 2023/12/04 15:29:03
- user: cg
- file: LargeFloat.st directory: libbasic2
- module: stx stc-classLibrary: libbasic2
Attention:
Experimental & Unfinished Code.
The implementation is neither complete nor tuned for performance - still being developed.
This class provides arbitrary precision floats.
I store floating point numbers in base 2 with some arbitrary precision (arbitrary number of bits).
I do inexact arithmetic like Float.
But I am very slow due to emulated (Large) Integer arithmetic... (compared to IEEE 754 hardwired)
Unlike Float, mantissa is not normalized to the form 1.mmmmmm
It is just stored as an integer.
The sign is stored in the mantissa.
biasedExponent is the power of two that multiplies the mantissa to form the number.
There is no limitation of exponent (overflow or underflow),
unless you succeed in exhausting the VM memory...
Like Float, my arithmetic operations are inexact.
They will round to nearest precision LargeFloat.
If two different precisions are used in arithmetic,
the result is expressed in the higher precision.
If the number is exact (i.e. was constructed from an integer),
I store 0 as precision.
Default operating mode is rounding, but might be one of the other possibility
(truncate floor ceiling).
Notice: the internals are completely non-IEEE;
although, I simulate an IEEE float when asked for exponent, mantissa, ebias, etc.
so some common bit-shuffling agorithms should work with me as well.
Instance Variables:
mantissa <Integer> the bits of mantissa including sign
exponent <Integer> the times two power to multiply the mantissa (floating binary scale)
precision <Magnitude> number of bits to be stored in mantissa when I am normalized
copyrightCOPYRIGHT (c) 2003 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.
class initialization
-
initialize
-
LargeFloat initialize
coercing & converting
-
coerce: aNumber
-
convert the argument aNumber into an instance of the receiver (class) and return it.
-
generality
-
return the generality value - see ArithmeticValue>>retry:coercing:
constants
-
NaN
-
LargeFloat NaN
(0.0 uncheckedDivide:0.0)
-
e
-
return the constant e as LargeFloat with at least 130 decimal digits precision
Usage example(s):
-
halfPi
-
return the constant pi/2 as quad precision double.
(returns approx. 200 bits of precision)
Usage example(s):
QuadFloat halfPi printfPrintString:'%.60f'
'1.570796326794896619231321691639751442098584699687552910487472'
LargeFloat halfPi printfPrintString:'%.60f'
'1.570796326794896619231321691639751442098584699687552910487472'
Wolfram says:
'1.5707963267948966192313216916397514420985846996875529104874722961539082031431044993140174126710585339910740432566411533235469223047752911158626797040642405587251420513509692605527798223114744774651909822144054878329667230642378241168933915826356009545728243'
(QDouble readFrom:'1.5707963267948966192313216916397514420985846996875529104874722961539082031431044993140174126710585339910740432566411533235469223047752911158626797040642405587251420513509692605527798223114744774651909822144054878329667230642378241168933915826356009545728243')
printfPrintString:'%.60f'
|
-
infinity
-
LargeFloat infinity
(1.0 uncheckedDivide:0.0)
-
ln10
-
return the ln(10) as largeFloat with at least 130 decimal digits precision
Usage example(s):
Ln10 := nil
LargeFloat ln10
|
-
ln2
-
return the ln(2) as largeFloat with at least 130 decimal digits precision
Usage example(s):
Ln2 := nil
LargeFloat ln2
|
-
negativeInfinity
-
LargeFloat negativeInfinity
(-1.0 uncheckedDivide:0.0)
-
one
-
return a one with the default precision
Usage example(s):
-
phi
-
return the constant phi as LargeFloat with at least 130 decimal digits precision
Usage example(s):
Phi := nil
LargeFloat phi
|
-
pi
-
return the constant pi as LargeFloat with at least 130 decimal digits precision
Usage example(s):
LargeFloat pi
(1 asLargeFloatPrecision:500) exp
|
-
sqrt2
-
return the sqrt(2) as largeFloat with at least 130 decimal digits precision
Usage example(s):
Sqrt2 := nil
LargeFloat sqrt2
|
-
sqrt3
-
return the sqrt(3) as largeFloat with at least 130 decimal digits precision
Usage example(s):
-
unity
-
return the neutral element for multiplication (1) as LargeFloat
Usage example(s):
-
zero
-
LargeFloat zero
instance creation
-
fromFraction: aFraction precision: n
-
return a largeFloat with value taken from aFraction
Usage example(s):
(1/2) asLargeFloat -> 0.500000000000
(1/3) asLargeFloat -> 0.333333333333
(1/3333) asLargeFloat -> 0.000300030003
(1/3333) asLargeFloat * 3333 -> 1.000000000000
LargeFloat fromFraction:(1/3) precision:100 -> 0.333333333333
(LargeFloat fromFraction:(1/3) precision:100)
+ (LargeFloat fromFraction:(1/3) precision:100) -> 0.666666666667
(LargeFloat fromFraction:(1/3) precision:500)
+ (LargeFloat fromFraction:(1/3) precision:500) -> 0.666666666667
|
-
fromInteger: anInteger
-
return a new largeFloat, given an integer value
Usage example(s):
LargeFloat fromInteger:123456
1 asLargeFloat
2 asLargeFloat
16 asLargeFloat
1000 factorial asLargeFloat
1000 factorial asLargeFloat asInteger = 1000 factorial
|
-
fromInteger: anInteger precision: n
-
LargeFloat fromInteger:123456 precision:6
1000 factorial asLargeFloat
1 asLargeFloat == 1 asLargeFloat
1.0 asLargeFloat == 1.0 asLargeFloat
-
fromLimitedPrecisionReal: aLimitedPrecisionReal
-
assumes that aLimitedPrecisionReal is a regular IEEE floating pnt number,
with a biased base2 exponent and hidden mantissa bit
Usage example(s):
LargeFloat fromLimitedPrecisionReal:(Float fmin) 2.2250738585072e-308 is: 2.2250738585072e-308
LargeFloat fromLimitedPrecisionReal:(Float fminDenormalized) 4.9406564584125e-324 is: 4.94065645841247e-324
LargeFloat fromLimitedPrecisionReal:(Float fmaxDenormalized) 2.2250738585072e-308 is: 2.2250738585072e-308
LargeFloat fromLimitedPrecisionReal:(LongFloat fmin) 3.36210314311209351e-4932 is: 3.362103143112093506e-4932
LargeFloat fromLimitedPrecisionReal:(LongFloat fminDenormalized) 3.95213325161012275e-4970 is: 3.645199531882474603e-4951
LargeFloat fromLimitedPrecisionReal:(LongFloat fmaxDenormalized) nan is: 3.362103143112093506e-4932
LargeFloat fromLimitedPrecisionReal:(ShortFloat fmin) 1.1755e-38 is: 1.175494e-38
LargeFloat fromLimitedPrecisionReal:(ShortFloat fminDenormalized) 1.4013e-45 is: 1.401298e-45
LargeFloat fromLimitedPrecisionReal:(ShortFloat fmaxDenormalized) 1.1755e-38 is: 1.175494e-38
1.0 asLargeFloat
123456 asLargeFloat /7
take a look at the precision...
1.0 asShortFloat asLargeFloat precision
1.0 asLongFloat asLargeFloat precision
1.0 asQDouble asLargeFloat precision
1 asLargeFloat
(5/3) asLargeFloat
(3/5) asLargeFloat
(1/2) asLargeFloat
2.0 asLargeFloat
20000.0 asLargeFloat
2e6 asLargeFloat
1e300 asLargeFloat
2e300 asLargeFloat
0.5 asLargeFloat
0.25 asLargeFloat
(1.0/20000.0) asLargeFloat
2e-6 asLargeFloat
2e-300 asLargeFloat
-1.0 asLargeFloat
-0.5 asLargeFloat
Float fmin asLargeFloat
Float fminDenormalized asLargeFloat
Float NaN asLargeFloat
Float infinity asLargeFloat
Float negativeInfinity asLargeFloat
0.0 asLargeFloat
1.0 asLargeFloat
0.5 asLargeFloat
-1.0 asLargeFloat
1e20 asLargeFloat
1e3 asLargeFloat
1e-3 asLargeFloat
-1e-3 asLargeFloat
Float fmin 2.2250738585072e-308
Float fmin asLargeFloat 2.2250738585072e-308
Float fminDenormalized 4.94065645841247e-324
Float fminDenormalized asLargeFloat 4.9406564584125e-324
LongFloat fmin 3.362103143112093506e-4932
LongFloat fmin asLargeFloat 3.36210314311209351e-4932
LongFloat fminDenormalized 3.645199531882474603e-4951
LongFloat fminDenormalized asLargeFloat 3.6451995318824746e-4951
|
-
integerMantissa: m unbiasedExponent: e precision: p
-
-
readFrom: aStringOrStream precision: precisionOrNil
-
if precisionOrNil is nil, the precision is computed from the number of
significant digits in the input
(adding a little bit, to ensure that we can later print it rounded to the
number of given digits; this approach is questionable,but affects only the
later printing and precision queries).
Otherwise,the given precision is assumed (give a non-nil precision, to prevent the
above)
Usage example(s):
self readFrom:'12345' precision:50 12345.0
self readFrom:'12345.678' precision:50 12345.678000000000
self readFrom:'12345e3' precision:50 12345000.0
self readFrom:'12345e1' precision:50 123450.0
self readFrom:'12345e0' precision:50 12345.0
self readFrom:'12345e-1' precision:50 1234.500000000000
self readFrom:'1.234e4' precision:50 12340.0
self phi
self readFrom:'12345' precision:nil 12345.0
self readFrom:'12345678901234567890' precision:nil 12345678901234567890.0
self readFrom:'1234.5678901234567890' precision:nil 1234.567890123457
self readFrom:'1234.5678901234567890' precision:200 1234.567890123457
self readFrom:'1234.56789012345674' precision:nil 1234.567890123457
self readFrom:'1234.56789012345674' precision:200 1234.567890123457
self readFrom:'1234.56789012345679' precision:nil 1234.567890123457
self readFrom:'1234.56789012345679' precision:200 1234.567890123457
|
queries
-
defaultPrecision
-
the default precision, if not specified explicitly
-
defaultPrintPrecision
-
the default number of digits when printing
-
defaultPrintfPrecision
-
the default number of digits when printing with printf's %f format.
Notice, that the C-language standard states that this should be 6;
however, we can adjust it on a per-class basis.
-
eBias
-
Answer the exponent's bias;
that is the offset of the zero exponent when stored
Usage example(s):
1.0 numBitsInExponent 11
1.0 eBias 1023
1.0 emin -1022
1.0 emax 1023
1.0 fmin 2.2250738585072E-308
1.0 fmax 1.79769313486232E+308
1.0 asLargeFloat numBitsInExponent - arbitrary; raises an error
1.0 asLargeFloat eBias - no such thing; raises an error
1.0 asLargeFloat emin - no such thing; raises an error
1.0 asLargeFloat emax - no such thing; raises an error
1.0 asLargeFloat fmin - no such thing; raises an error
1.0 asLargeFloat fmax - no such thing; raises an error
|
-
emax
-
The largest exponent value allowed by instances of this class.
-
emin
-
The smallest exponent value allowed by (normalized) instances of this class.
There is no minimum here
-
fmax
-
there is no maximum
-
fmaxDenormalized
-
there is no minimum
-
fmin
-
return the smallest normalized non-zero value that instances of me can hold.
There is no minimum here
Usage example(s):
Float fmin 2.2250738585072e-308
LargeFloat fmin 0.0
|
-
fminDenormalized
-
there is no minimum
-
isIEEEFormat
-
-
numBitsInMantissa
-
notice: this is an instance specific value; thus only a default value is returned here
-
numHiddenBits
-
-
radix
-
answer the radix of a LargeFloat's exponent
accessing
-
biasedExponent
-
anwser the biased exponent;
this is not what a standard floating point would return (adding its ebias to it),
(but I have an eBias of 0, also answer eBias with 0;
so my biasedExponent is the same as the unbiased)
-
exponent
-
anwser the floating point like exponent e of self,
normalized such that:
mantissa * (2 raisedTo: e)
Usage example(s):
1.0 exponent 1
1.0 asLargeFloat exponent 0
2.0 exponent
2.0 asLargeFloat exponent
3.0 exponent
3.0 asLargeFloat exponent
3.0 mantissa
3.0 asLargeFloat mantissa
3.0 mantissa * (2 raisedTo:3.0 exponent)
3.0 asLargeFloat mantissa * (2 raisedTo:3.0 asLargeFloat exponent)
4.0 exponent
4.0 asLargeFloat exponent
10.0 exponent
10.0 asLargeFloat exponent
0.5 exponent
0.4 exponent
0.25 exponent
0.2 exponent
0.00000011111 exponent
0.0 exponent
1e1000 exponent
LargeFloat NaN exponent
LargeFloat infinity exponent
|
-
integerMantissa
-
return my internal mantissa;
that is an integer which needs to be shifted right,
precision number of bits to become a 'real' IEEE mantissa.
This returns an integer
-
mantissa
-
return what would be the normalized float's mantissa if I was an IEEE float.
This assumes that a float's mantissa is normalized to
0.5 .. 1.0 and the number's value is:
mantissa * 2^exp.
Returns a float of the receiver's type
-
nextToward: aNumber
-
answer the nearest floating point number to self with same precision than self,
toward the direction of aNumber argument.
If the nearest one falls on the other side of aNumber, than answer a Number
-
precision
-
answer the precision (the number of bits in the mantissa) of my elements (in bits).
If the receiver has never been given a precision, a default value (200) is returned.
-
precisionOrNil
-
answer the precision (the number of bits in the mantissa) of my elements (in bits).
If the receiver has not been given a precision, nil is returned
-
significand
-
arithmetic
-
* aNumber
-
return the product of the receiver and the argument.
-
+ aNumber
-
return the sum of the receiver and the argument
Usage example(s):
1.0 asLargeFloat + 20 asLargeFloat
1.0 asLargeFloat + 20
1.0 asLargeFloat + 20.0
1.0 asLargeFloat + ( 2 / 5 )
1.0 asLargeFloat + 0.4 asLargeFloat
20 asLargeFloat + 1.0 asLargeFloat
20 + 1.0 asLargeFloat
20.0 + 1.0 asLargeFloat
( 2 / 5 ) + 1.0 asLargeFloat
|
-
- aNumber
-
Return the difference of the receiver and the argument.
-
/ aNumber
-
return the quotient of the receiver and the argument, aNumber
-
// aNumber
-
return the integer quotient of dividing the receiver by aNumber with
truncation towards negative infinity.
Usage example(s):
8 // 2 -> 4
-8 // 2 -> -4
9 // 2 -> 4
-9 // 2 -> -5
8 // -2 -> -4
-8 // -2 -> 4
9 // -2 -> -5
-9 // -2 -> 4
8 asFloat // 2 -> 4
-8 asFloat // 2 -> -4
9 asFloat // 2 -> 4
-9 asFloat // 2 -> -5
8 asFloat // -2 -> -4
-8 asFloat // -2 -> 4
9 asFloat // -2 -> -5
-9 asFloat // -2 -> 4
8 asLargeFloat // 2 -> 4
-8 asLargeFloat // 2 -> -4
9 asLargeFloat // 2 -> 4
-9 asLargeFloat // 2 -> -5
8 asLargeFloat // -2 -> -4
-8 asLargeFloat // -2 -> 4
9 asLargeFloat // -2 -> -5
-9 asLargeFloat // -2 -> 4
|
-
naiveRaisedToInteger: n
-
Very naive algorithm: use full precision.
Use only for small n
-
negated
-
LargeFloat unity negated -1.0
LargeFloat zero negated 0.0
0.0 asLargeFloat negated 0.0
-
raisedToInteger: anInteger
-
return the receiver raised to an integer exp.
The caller must ensure that the arg is actually an integer
-
reciprocal
-
(comment from inherited method)
return the receiver's reciprocal
-
squared
-
return receiver * receiver.
-
timesTwoPower: n
-
Return the receiver multiplied by 2 raised to the power of the argument.
I.e. self * (2**n).
Usage example(s):
1 timesTwoPower:10 -> 1024
2**10 -> 1024
3 timesTwoPower:10 -> 3072
3 * (2**10) -> 3072
1 timesTwoPower:20 -> 1048576
2**20 -> 1048576
(1 timesTwoPower:10) timesTwoPower:10 -> 1048576
1.0 timesTwoPower:10 -> 1024.0
1.0 timesTwoPower:20 -> 1048576.0
(1.0 asLargeFloatPrecision:100) timesTwoPower:10 -> 1024.0
(1.0 asLargeFloatPrecision:100) timesTwoPower:20 -> 1048576.0
LargeFloat infinity timesTwoPower:20 -> inf
|
coercing & converting
-
asFloat
-
Convert to a IEEE 754 double precision floating point.
Might return infinity if the receiver cannot be represented as a float
Usage example(s):
100 factorial 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
100 factorial asFloat 9.33262154439442e+157
100 factorial asLongFloat 9.332621544394415268E+157
100 factorial asLargeFloat 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000.0
100 factorial asLargeFloat asFloat 9.33262154439442e+157
200 factorial asLargeFloat asLongFloat 7.886578673647905467E+374
1000 factorial asLargeFloat asFloat inf
1000 factorial asLargeFloat asLongFloat 4.023872600770937921E+2567
|
-
asFraction
-
Convert to a fraction.
-
asInteger
-
return an integer with same value - might truncate
Usage example(s):
(self new exponent:0 mantissa:100) asInteger
(self new exponent:1 mantissa:100) asInteger
(self new exponent:-1 mantissa:100) asInteger
|
-
asLargeFloat
-
return a large float with same value - that's me
-
asLargeFloatPrecision: n
-
possibly change the precision
-
asLongFloat
-
Convert to a IEEE 754 extended precision floating point.
Might return infinity if the receiver cannot be represented as an extended float
Usage example(s):
100 factorial asLargeFloat asShortFloat 9.33262124234219e+157
100 factorial asLargeFloat asFloat 9.33262154439442E+157
100 factorial asLargeFloat asLongFloat 9.332621544394415097e+157
120 factorial asLargeFloat asShortFloat 9.33262124234219e+157
100 factorial asLargeFloat asFloat 9.33262154439442E+157
100 factorial asLargeFloat asLongFloat 9.332621544394415097e+157
200 factorial asLargeFloat asShortFloat inf
200 factorial asLargeFloat asFloat inf
200 factorial asLargeFloat asLongFloat 7.886578673647905467E+374
1000 factorial asLargeFloat asLongFloat 4.023872600770937921E+2567
|
-
asShortFloat
-
Convert to a IEEE 754 single precision floating point.
Might return infinity if the receiver cannot be represented as a float32
Usage example(s):
ShortFloat fmax 3.402823e+38
ShortFloat fmax asLargeFloat 340282346638528859811704183484516925440.0
ShortFloat fmax asLargeFloat asShortFloat 3.402823e+38
30 factorial asLargeFloat asShortFloat 2.652529e+32
34 factorial asLargeFloat asShortFloat 2.952328e+38
35 factorial asLargeFloat asShortFloat inf
50 factorial asLargeFloat asShortFloat inf
100 factorial asLargeFloat asShortFloat inf
100 factorial asLargeFloat asFloat 9.33262154439442E+157
100 factorial asLargeFloat asLongFloat 9.332621544394415097e+157
|
-
asTrueFraction
-
Answer a fraction or integer that EXACTLY represents self.
Usage example(s):
0.3 asFloat asTrueFraction
0.3 asShortFloat asTrueFraction
0.3 asLongFloat asTrueFraction
0.3 asLargeFloat asTrueFraction
1 asLargeFloat asTrueFraction
2 asLargeFloat asTrueFraction
0.5 asLargeFloat asTrueFraction
0.25 asLargeFloat asTrueFraction
-0.25 asLargeFloat asTrueFraction
0.125 asLargeFloat asTrueFraction
-0.125 asLargeFloat asTrueFraction
1.25 asLargeFloat asTrueFraction
3e37 asLargeFloat asTrueFraction
LargeFloat NaN asTrueFraction -> error
LargeFloat infinity asTrueFraction -> error
LargeFloat negativeInfinity asTrueFraction -> error
|
-
coerce: aNumber
-
return the argument as a LargeFloat (with whichever precision is larger).
The larger precision is required, because we might be called to coerce a QuadFloat
with a less-precision LargeFloat (although LargeFloat generality is higher)
-
generality
-
return the generality value - see ArithmeticValue>>retry:coercing:
-
specialValueAs: floatClass
-
either zero, NaN or INF
comparing
-
< aNumber
-
return true, if the argument is greater
-
= aNumber
-
return true, if the argument is equal in value
Usage example(s):
LargeFloat unity = LargeFloat zero
LargeFloat unity = LargeFloat unity
LargeFloat unity = nil
LargeFloat unity ~= nil
|
-
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.
Usage example(s):
LargeFloat unity hash
LargeFloat zero hash
3 hash
3.0 hash
3.1 hash
3.14159 hash
31.4159 hash
3.141591 hash
1.234567890123456 hash
1.234567890123457 hash
Set withAll:#(3 3.0 99 99.0 3.1415)
|
constants
-
one
-
return a one with my precision
-
pi
-
answer the value of pi rounded to my precision.
Note: use the Brent-Salamin Arithmetic Geometric Mean algorithm
Usage example(s):
Number piDigits
Time microsecondsToRun:[(1.0 asLargeFloatPrecision:2000) pi]
(1.0 asLargeFloatPrecision:400) pi
-> 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648564
wolfram:
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648567
|
-
piDoublePrecision
-
-
zero
-
return a zero with my precision
copying-private
-
postCopy
-
(comment from inherited method)
this is for compatibility with ST-80 code, which uses postCopy for
cleanup after copying, while ST/X passes the original in postCopyFrom:
(see there)
double dispatching
-
differenceFromLargeFloat: aLargeFloat
-
INF or NaN
-
equalFromLargeFloat: aLargeFloat
-
assuming normalized numbers, they cannot be equal then
-
lessFromLargeFloat: aLargeFloat
-
return true if aLargeFloat < self
-
productFromLargeFloat: aLargeFloat
-
INF or NaN
-
quotientFromLargeFloat: aLargeFloat
-
Return the quotient of the argument, aLargeFloat and the receiver.
(i.e. divide aLargeFloat by self)
Sent when aLargeFloat does not know how to divide by the receiver.
-
sumFromLargeFloat: aLargeFloat
-
INF or NaN
initialization
-
setPrecisionTo: n
-
mathematical functions
-
agm: aNumber
-
return the arithmetic-geometric mean agm(a, b) of the receiver (a) and the argument, b.
See https://en.wikipedia.org/wiki/Arithmetic-geometric_mean
and http://www.wolframalpha.com/input/?i=agm(24,+6)
-
exp
-
Answer the exponential of the receiver.
Usage example(s):
Use following decomposition:
x exp = (2 ln * q + r) exp.
x exp = (2**q * r exp)
|
Usage example(s):
now compute r exp by power series expansion
we compute (r/(2**p)) exp ** (2**p) in order to have faster convergence
|
-
integerLog10
-
1234.567 integerLog10 3
1234.567 asLargeFloat integerLog10 3
0.000001234 integerLog10 -5
0.000001234 asLargeFloat integerLog10 -5
(10.5 raisedTo:100) integerLog10 102
(10.5 asLargeFloat raisedTo:100) integerLog10 102
-
integerLog2
-
1234.567 integerLog2 10
1234.567 asLargeFloat integerLog2 10
0.000001234 integerLog2 -19
0.000001234 asLargeFloat integerLog2 -19
(10.5 raisedTo:100) integerLog2 339
(10.5 asLargeFloat raisedTo:100) integerLog2 339
-
ln
-
Answer the naperian (natural) logarithm of the receiver.
Usage example(s):
x ln = Pi / (2 * (1 agm: 4/x) ).
|
Usage example(s):
If x not big enough, compute (x timesTwoPower: p) ln - (2 ln * p)
|
Usage example(s):
selfHighRes inPlaceReciprocal "Use ln(1/x) => - ln(x)"
|
Usage example(s):
0.00001 ln -11.5129254649702
0.00001 asShortFloat ln -11.51293
0.00001 asLongFloat ln -11.51292546497022834
0.00001 asIEEEFloat ln -11.51293
0.00001 asLargeFloat ln -11.512925464970
1 ln 0.0
1 asLargeFloat ln 0.000000000000
1 asLargeFloat log10 0.000000000000
|
-
log10
-
not always: we might loose precision here
Usage example(s):
1234.567 log10 3.09151466408626
1234.567 asLargeFloat log10 3.09151466408626
(10.5 raisedTo:100) log10 102.118929906994
(10.5 asLargeFloat raisedTo:100) log10 102.118929906994
|
-
log2
-
not always: we might loose precision here
Usage example(s):
1234.567 log2 10.2697894183844
1234.567 asLargeFloat log2 10.2697894183844
(LargeFloat fromString:'1234.567') log2 10.269789418384422758312631399945212567112793956158107187152
(10.5 raisedTo:100) log2 339.231742277876
(10.5 asLargeFloat raisedTo:100) log2
|
-
sqrt
-
Answer the square root of the receiver.
Usage example(s):
"Initial guess for sqrt(1/n)"
|
Usage example(s):
"use iterations x(k+1) := x*( 1 + (1-x*x*n)/2) to guess sqrt(1/n)"
|
Usage example(s):
(144 asLargeFloatPrecision:200) sqrt
(-144 asLargeFloatPrecision:200) sqrt
ShortFloat decimalPrecision 7
(2 asShortFloat) sqrt printfPrintString:'%8.7f'
-> 1.4142136
Float decimalPrecision 15
(2 asFloat) sqrt printfPrintString:'%16.15f'
-> 1.414213562373095
LongFloat decimalPrecision 19
(2 asLongFloat) sqrt printfPrintString:'%20.19Lf'
-> 1.4142135623730950488
QuadFloat decimalPrecision 34
(2 asQuadFloat) sqrt printfPrintString:'%34.33f'
-> 1.414213562373095048801688724209698
QDouble decimalPrecision 61
(2 asQDouble) sqrt printfPrintString:'%61.60f'
-> 1.414213562373095048801688724209698078569671875376948073176680
OctaFloat decimalPrecision 71
(2 asOctaFloat) sqrt printfPrintString:'%71.70f'
-> 1.4142135623730950488016887242096980785696718753769480731766797379907325
(2 asLargeFloatPrecision:1000) sqrt printfPrintString:'%300.299f'
-> 1.41421356237309504880168872420969807856967187537694807317667973799073247846210703885038753432764157273501384623091229702492483605585073721264412149709993583141322266592750559275579995050115278206057147010955997160597027453459686201472851741864088919860955232923048430871432145083976260362799525140799
|
printing
-
absPrintExactlyOn: aStream base: base
-
Print my value on a stream in the given base.
Based upon the algorithm outlined in:
Robert G. Burger and R. Kent Dybvig
Printing Floating Point Numbers Quickly and Accurately
ACM SIGPLAN 1996 Conference on Programming Language Design and Implementation
June 1996.
This version guarantees that the printed representation exactly represents my value
by using exact integer arithmetic.
-
asMinimalDecimalFraction
-
Answer the shortest decimal Fraction that will equal self when converted back asFloat.
A decimal Fraction has only powers of 2 and 5 as decnominator.
For example, 0.1 asLargeFloat asMinimalDecimalFraction = (1/10).
-
defaultPrintPrecision
-
(comment from inherited method)
the default number of digits when printing
-
printOn: aStream
-
a zero mantissa is impossible - except for zero and a few others
Usage example(s):
(self printfPrintString:e'%.{self defaultPrintPrecision}g') printOn:aStream.
|
Usage example(s):
LargeFloat NaN printOn:Transcript
|
-
printOn: aStream base: base
-
(2 asLargeFloat raisedTo:1000) printOn:Transcript base:16
(2 asLargeFloat raisedTo:1000) printOn:Transcript base:10
-
storeOn: aStream
-
Modified (format): / 24-07-2019 / 09:55:11 / Claus Gittinger
private
-
cos: x
-
Evaluate the cosine of x by recursive cos(2x) formula and power series expansion.
Note that it is better to use this method with x <= pi/4.
-
digitCompare: b
-
both are positive or negative.
answer +1 if i am of greater magnitude, -1 if i am of smaller magnitude, 0 if equal magnitude
-
inPlaceAbs
-
destructive
-
inPlaceAdd: b
-
destructive
Usage example(s):
|v|
v := 0 asLargeFloat.
v inPlaceAdd: 1 asLargeFloat.
v inPlaceAdd: 1 asLargeFloat.
v inPlaceAdd: 0.5 asLargeFloat.
v
|
Usage example(s):
|v|
v := 0.5 asLargeFloat.
v inPlaceAdd: 0.4 asLargeFloat.
v
|
Usage example(s):
|v|
v := 0.5 asLargeFloat.
v inPlaceAdd: 0.04 asLargeFloat.
v
|
Usage example(s):
|v|
v := 0.5 asLargeFloat.
v inPlaceAdd: 0.004 asLargeFloat.
v
|
-
inPlaceAddNoRound: b
-
destructive
-
inPlaceCopy: b
-
copy another arbitrary precision float into self
-
inPlaceDivideBy: y
-
Reference: Accelerating Correctly Rounded Floating-Point Division when the Divisor
Is Known in Advance - Nicolas Brisebarre,
Jean-Michel Muller, Member, IEEE, and
Saurabh Kumar Raina -
http://perso.ens-lyon.fr/jean-michel.muller/DivIEEETC-aug04.pdf
-
inPlaceMultiplyBy: b
-
2.4 asLargeFloat inPlaceMultiplyBy:2.0 asLargeFloat
2.5 asLargeFloat inPlaceMultiplyBy:2.0 asLargeFloat
-
inPlaceMultiplyBy: b andAccumulate: c
-
only do rounding after the two operations.
This is the traditional muladd operation in aritmetic units
Usage example(s):
2.4 asLargeFloat inPlaceMultiplyBy:2.0 asLargeFloat andAccumulate:10.0 asLargeFloat
|
-
inPlaceMultiplyNoRoundBy: b
-
2.4 asLargeFloat inPlaceMultiplyNoRoundBy:2.0
-
inPlaceNegated
-
destructive
-
inPlaceReciprocal
-
destructive
-
inPlaceSqrt
-
destructive
-
inPlaceSubtract: b
-
destructive
-
inPlaceSubtractNoRound: b
-
destructive
-
inPlaceTimesTwoPower: n
-
destructive
Usage example(s):
1.0 timesTwoPower:2 -> 4.0
1.0 timesTwoPower:3 -> 8.0
1.0 timesTwoPower:4 -> 16.0
1.0 asLargeFloat copy inPlaceTimesTwoPower:2 4.0
1.0 asLargeFloat copy inPlaceTimesTwoPower:3 8.0
1.0 asLargeFloat copy inPlaceTimesTwoPower:4 16.0
1.0 asLargeFloat copy inPlaceTimesTwoPower:-1 0.5
1.0 asLargeFloat copy inPlaceTimesTwoPower:-2 0.25
|
-
integerMantissa: mantissaArg biasedExponent: exponentArg precision: precisionArg
-
set instance variables.
Notice, that the float's value is
m * 2^e
As we store the mantissa as an (unnormalized) integer,
the biasedExponent will usually be negative,
and the mantissa will be a (huge) integer >= 1
(however, the above formula still holds)
-
integerMantissa: mantissaArg unbiasedExponent: exponentArg precision: precisionArg
-
set instance variables.
Notice, that the float's value is
m * 2^e
As we store the mantissa as an (unnormalized) integer,
the biasedExponent will usually be negative,
and the mantissa will be a (huge) integer >= 1
(however, the above formula still holds)
-
minPrecisionWith: otherPrecision
-
-
moduloNegPiToPi
-
answer a copy of the receiver modulo 2*pi, with doubled precision
Usage example(s):
(LargeFloat pi * 2) moduloNegPiToPi
(LargeFloat pi * 3) moduloNegPiToPi
(LargeFloat pi * 19) moduloNegPiToPi
(LargeFloat pi * 19.5) moduloNegPiToPi
(LargeFloat pi * -10) moduloNegPiToPi
|
-
normalize
-
destructive
-
powerExpansionArCoshp1Precision: precBits
-
Evaluate arcosh(x+1)/sqrt(2*x) for the receiver x by power series expansion.
The algorithm is interesting when the receiver is close to zero
-
powerExpansionArSinhPrecision: precBits
-
Evaluate the area hypebolic sine of the receiver by power series expansion.
The algorithm is interesting when the receiver is close to zero
-
powerExpansionArTanhPrecision: precBits
-
Evaluate the area hyperbolic tangent of the receiver by power series expansion.
arTanh (x) = x (1 + x^2/3 + x^4/5 + ... ) for -1 < x < 1
The algorithm is interesting when the receiver is close to zero
-
powerExpansionArcSinPrecision: precBits
-
Evaluate the arc sine of the receiver by power series expansion.
The algorithm is interesting when the receiver is close to zero
-
powerExpansionArcTanPrecision: precBits
-
Evaluate the arc tangent of the receiver by power series expansion.
arcTan (x) = x (1 - x^2/3 + x^4/5 - ... ) for -1 < x < 1
The algorithm is interesting when the receiver is close to zero
-
powerExpansionCosPrecision: precBits
-
Evaluate the cosine of the receiver by power series expansion.
The algorithm is interesting when the receiver is close to zero
Usage example(s):
1 cos 0.54030230586814
(1 asLargeFloatPrecision:300) cos 0.540302305868
(1 asLargeFloatPrecision:300) powerExpansionCosPrecision:300 0.540302305868
|
-
powerExpansionCoshPrecision: precBits
-
Evaluate the hyperbolic cosine of the receiver by power series expansion.
The algorithm is interesting when the receiver is close to zero
Usage example(s):
1 cosh 1.54308063481524
1 asQuadFloat cosh 1.54308063
1 asQDouble cosh 1.543080635
(1 asLargeFloatPrecision:300) cosh 1.543080634815
(1 asLargeFloatPrecision:300) powerExpansionCoshPrecision:300 1.543080634815
|
-
powerExpansionLnPrecision: precBits
-
Evaluate the naperian logarithm of the receiver by power series expansion.
For quadratic convergence, use:
ln ((1+y)/(1-y)) = 2 y (1 + y^2/3 + y^4/5 + ... ) = 2 ar tanh( y )
(1+y)/(1-y) = self => y = (self-1)/(self+1)
This algorithm is interesting when the receiver is close to 1
Usage example(s):
5 ln 1.6094379124341
5 asLargeFloat powerExpansionLnPrecision:100 1.609437912434
5 asLargeFloat powerExpansionLnPrecision:200
5 asLargeFloat powerExpansionLnPrecision:400
5 asLargeFloat powerExpansionLnPrecision:1000
|
-
powerExpansionSinCosPrecision: precBits
-
Evaluate the sine and cosine of the receiver by power series expansion.
The algorithm is interesting when the receiver is close to zero
-
powerExpansionSinPrecision: precBits
-
Evaluate the sine of the receiver by power series expansion.
The algorithm is interesting when the receiver is close to zero
-
powerExpansionSinhPrecision: precBits
-
Evaluate the hyperbolic sine of the receiver by power series expansion.
The algorithm is interesting when the receiver is close to zero
-
powerExpansionTanPrecision: precBits
-
Evaluate the tangent of the receiver by power series expansion.
The algorithm is interesting when the receiver is close to zero
-
powerExpansionTanhPrecision: precBits
-
Evaluate the hyperbolic tangent of the receiver by power series expansion.
The algorithm is interesting when the receiver is close to zero
-
precision: precisionArg
-
set instance variables.
Notice, that the float's value is m * 2^e
-
precisionInMantissa
-
this is equal to precision only if we are normalized.
If we are reduced (low bits being zero are removed), then it will be less.
If we haven't been rounded/truncated then it will be more
-
privateRoundToPrecision
-
destructive inplace round
apply algorithm round to nearest even used by IEEE arithmetic
-
privateRoundToPrecision: precision
-
destructive inplace round
apply algorithm round to nearest even used by IEEE arithmetic
-
privateTruncate
-
destructive remove trailing bits if they exceed our allocated number of bits
-
reduce
-
remove trailing zero bits from mantissa so that we can do arithmetic on smaller integer
(that will un-normalize self)
-
setMantissa: mantissaArg unbiasedExponent: exponentArg
-
set instance variables.
Notice, that the float's value is m * 2^e
-
shift: m by: d
-
shift mantissa m absolute value by some d bits, then restore sign
-
sin: x
-
Evaluate the sine of x by sin(5x) formula and power series expansion.
-
sincos: x
-
Evaluate the sine and cosine of x by recursive sin(2x) and cos(2x) formula and power series expansion.
Note that it is better to use this method with x <= pi/4.
queries
-
epsilon
-
return the maximum relative spacing of instances of mySelf
(i.e. the value-delta of the least significant bit)
according to ISO C standard;
Ada, C, C++ and Python language constants;
Mathematica, MATLAB and Octave; and various textbooks
see https://en.wikipedia.org/wiki/Machine_epsilon
Usage example(s):
-
exponentBits
-
simulatre an IEEE float's biased exponentbits
-
isExact
-
DO NOT USE; unfinished, and currenty not true
return true, if the number represented by the receiver is exact
or false, if it is an approximation.
If the receiver resulted from converting an integer, it will be exact.
Usage example(s):
1 asLargeFloat isExact
1.0 asLargeFloat isExact
|
-
mantissaBits
-
simulate an IEEE float's normalized mantissaBits
(my internal mantissa is not normalized, so clear the high bit
to make it look like a normalized IEEE mantissa with hidden bit)
-
nextFloat: nUlps
-
1 asLargeFloat nextFloat:1
(1 asLargeFloat nextFloat:1) - 1
(1 asLargeFloat nextFloat:10)
(1 asLargeFloat nextFloat:10) - 1
-
numBitsInExponent
-
I have as amny as needed;
but simulate having at least 20
-
numBitsInMantissa
-
answer the number of bits in the mantissa (the significant).
Here the number of bits in the mantissa is dynamic.
-
numHiddenBits
-
-
predecessor
-
-
successor
-
-
ulp
-
answer the distance between me and the next representable number
Usage example(s):
(0.0 asLargeFloat nextFloat:1) - 0.0 asLargeFloat -> 1.24460305557e-60
0.0 asLargeFloat ulp -> 1.24460305557e-60
1.0 asLargeFloat ulp -> 2.22044604925e-16
(1/100000) asLargeFloat ulp -> 2.36364252615e-130
-1.0 asLargeFloat ulp -> 2.22044604925e-16
(1.0 asLargeFloatPrecision:200) ulp -> 1.24460305557e-60
(0.0 asLargeFloatPrecision:400) ulp -> 7.7451838297e-121
(100000 asLargeFloatPrecision:400) ulp -> 2.4784588255e-114
|
testing
-
isAnExactFloat
-
-
isFinite
-
return true, if the receiver is a finite float (not NaN and not +/-INF)
-
isInfinite
-
return true, if the receiver is an infinite float (+Inf or -Inf).
These are not created by ST/X float operations (they raise an exception);
however, inline C-code could produce them.
-
isNaN
-
return true, if the receiver is an invalid float (NaN - not a number).
These are usually not created by ST/X float operations (they raise an exception);
however, inline C-code or proceeded exceptions or reading from a stream
could produce them.
-
isZero
-
return true, if the receiver is zero
-
negative
-
return true if the receiver is negative
-
positive
-
return true if the receiver is greater or equal to zero (not negative).
0.0 and -0.0 are positive for now.
-
sign
-
return the sign of the receiver
Usage example(s):
LargeFloat nan sign
LargeFloat infinity sign
LargeFloat infinity negated sign
0 asLargeFloat sign
1 asLargeFloat sign
-1 asLargeFloat sign
|
trigonometric
-
arcCos
-
Evaluate the arc cosine of the receiver.
-
arcSin
-
Evaluate the arc sine of the receiver.
Usage example(s):
DomainError signal: 'cannot compute arcSin of a number greater than 1'
|
Usage example(s):
Usage example(s):
self negative ifTrue: [arcSin inPlaceNegated].
|
Usage example(s):
^arcSin asLargeFloatPrecision: precision
|
-
arcTan
-
Evaluate the arc tangent of the receiver.
-
arcTan: denominator
-
Evaluate the four quadrant arc tangent of the argument denominator (x) and the receiver (y).
-
cos
-
Evaluate the cosine of the receiver
Usage example(s):
-
sin
-
Evaluate the sine of the receiver
Usage example(s):
-
sincos
-
Evaluate the sine and cosine of the receiver
-
tan
-
Evaluate the tangent of the receiver
Usage example(s):
| pi halfPi quarterPi x sincos neg tan |
|
Usage example(s):
tan := x powerExpansionTanPrecision: x precision
|
Usage example(s):
Usage example(s):
neg ifTrue: [tan inPlaceNegated].
|
Usage example(s):
^tan asLargeFloatPrecision: precision
|
trigonometric - hyperbolic
-
arCosh
-
Evaluate the hyperbolic area cosine of the receiver.
-
arSinh
-
Evaluate the hyperbolic area sine of the receiver.
-
arTanh
-
Evaluate the hyperbolic area tangent of the receiver.
-
cosh
-
return the hyperbolic cosine of the receiver (interpreted as radians)
-
sinh
-
@Commented by exept MBP at: 2021-10-06 09:40 Reason:
Usage example(s):
(0 asLargeFloatPrecision:100) sinh 0.0
(10 asLargeFloatPrecision:100) sinh 11013.232874703393377236524554848
|
-
tanh
-
(2 asLargeFloatPrecision:100) tanh 0.964027580076
(10 asLargeFloatPrecision:100) tanh 0.999999995878
truncation & rounding
-
truncated
-
answer the integer that is nearest to self in the interval between zero and self
Usage example(s):
0.4 asLargeFloat truncated => 0
2.4 asLargeFloat truncated => 2
24.0 asLargeFloat truncated => 24
2e34 asLargeFloat truncated => 20000000000000001217347628954550272 -- error alreay in 2e34
(2 raisedTo:34) asLargeFloat truncated => 17179869184
2e100 asLargeFloat truncated => 20000000000000004203395606646656502775645430774928376064376333219774720047965581599435510382130626560
2 * (10 asLargeFloat raisedTo:100) truncated => inexact due to limited nr of bits (200)
(2 * ((10 asLargeFloatPrecision:500) raisedTo:100)) truncated => 20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0
-0.4 asLargeFloat truncated => 0
-2.4 asLargeFloat truncated => -2
-24.0 asLargeFloat truncated
-2e34 asLargeFloat truncated
-2e100 asLargeFloat truncated
|
pi should be (500 digits below):
3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360726024914127372458700660631558817488152092096282925409171536436789259036001133053054882046652138414695194151160943305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912
'%500.498e' printf:{ (1.0 asLargeFloatPrecision:500) pi }
1000 factorial as a LargeFloat:
(1 to:1000) inject:1 asLargeFloat into:[:p :m | p * m]
1000 factorial as an Integer:
(1 to:1000) inject:1 into:[:p :m | p * m]
compute 20000.0 factorial:
Time millisecondsToRun:[
(1 to:20000) inject:1 asLargeFloat into:[:p :m | p * m]
] -> 210
compute 20000 factorial:
Time millisecondsToRun:[
(1 to:20000) inject:1 into:[:p :m | p * m]
] -> 160
|