eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'QDouble':

Home

Documentation
www.exept.de
Everywhere
for:
[back]

Class: QDouble


Inheritance:

   Object
   |
   +--Magnitude
      |
      +--ArithmeticValue
         |
         +--Number
            |
            +--LimitedPrecisionReal
               |
               +--QDouble

Package:
stx:libbasic2
Category:
Magnitude-Numbers
Version:
rev: 1.137 date: 2023/08/08 11:12:49
user: cg
file: QDouble.st directory: libbasic2
module: stx stc-classLibrary: libbasic2

Description:


ATTENTION: ongoing, unfinished work.
No warranty that this works correctly...

QDoubles represent rational numbers with extended, but still limited precision.

In contrast to Floats (which use the C-compiler's native 64bit 'double' format),
QDoubles give you roughly 200 bit or approx. 60 decimal digits of precision.

Representation:
    QDoubles use 4 IEEE doubles, each keeping 53 bits of precision.
    A qDouble's value is the sum of those 4 doubles,
    and a qDouble keeps this unevaluated sum as its state.
    (due to overlap and rounding, the final precision is less than 53*4)
    The exponent range is still the double exponent range,
    but the number of mantissa bits is rougly multiplied by 4;
    qDoubles can also represent the sum of upto 4 wildly distant numbers,
    such as 1e200 + 1e-200 (but only up to 4 such terms).

Range and Precision of Storage Formats: see LimitedPrecisionReal >> documentation
The number of decimal digits:
    OctaFloat decimalPrecision   -> 71
    QDouble decimalPrecision     -> 61
    QuadFloat decimalPrecision   -> 34
    LongFloat decimalPrecision   -> 19
    Float decimalPrecision       -> 16
    ShortFloat decimalPrecision  -> 7
    LargeFloat decimalPrecision  -> any (default is 60)

The number of bits:
    OctaFloat precision          -> 237
    QDouble precision            -> 204
    QuadFloat precision          -> 113
    LongFloat precision          -> 64
    Float precision              -> 53
    ShortFloat precision         -> 24
    LargeFloat precision         -> any (default is 200)

QDoubles are able to represent sums of wildly distant numbers:
    1e200 + 1e-15 + 1e-100                              -> 1E+200  (loosing all small addends)
    (1e200 + 1e-15 + 1e-100) - 1e200                    -> 0
    (1e200 + 1e-15 + 1e-100) - 1e200 - 1e-15            -> -1e-15
    (1e200 + 1e-15 + 1e-100) - 1e200 - 1e-100           -> -1E-100
    (1e200 + 1e-15 + 1e-100) - 1e200 - 1e-15 - 1e-100   -> -1E-015

    1e200 asQDouble + 1e-15 + 1e-100                    -> 1E+200  (but small addends are still there)
    (1e200 asQDouble + 1e-15 + 1e-100) - 1e200          -> 1.0e-15
    (1e200 asQDouble + 1e-15 + 1e-100) - 1e200 - 1e-15  -> 1E-100
    (1e200 asQDouble + 1e-15 + 1e-100) - 1e200 - 1e-100 -> 1E-015
    (1e200 asQDouble + 1e-15 + 1e-100) - 1e200 - 1e-15 - 1e-100   -> 0.0

Notice:
    when assigning a converted double precision number as in:
        qd := 0.1 asQDouble.
    you still get only a regular double precision approximation to 0.1
    because the error is already inherit in the double.

    For a full precision constant, you (currently) need to convert from a string
    (because the compilers do not know about them, yet):
        qd := QDouble readFrom:'0.1'.

    To see the error of the double precision version, compute:
        (0.1 asQDouble) - (QDouble readFrom:'0.1')

copyright

COPYRIGHT (c) 2017 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 protocol:

coercing & converting
o  coerce: aNumber
convert the argument aNumber into an instance of the receiver (class) and return it.

constants
o  NaN
return a QDouble which represents not-a-Number (i.e. an invalid number)

o  e
return the constant e as quad precision double.
(returns approx. 200 bits of precision)

Usage example(s):

     self e printfPrintString:'%.61f'
       -> '2.7182818284590452353602874713526624977572470936999595749669676'
     Wolfram says:
	   2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746

o  fmax
return the largest value that instances of me can represent

Usage example(s):

     Float fmax           1.797693134862316e+308   
     Float fmax asQDouble 1.79769313486232e+308  
     QDouble fmax         1.7976931348623140116810111328051981204942367928321477092558725e+308

o  fmaxDenormalized
the larges denormalized value which can be represented by instances of this class;
should actually be sent to the instance,
because of IEEEFloat, which has instance-specific representation.

Usage example(s):

     QDouble fmaxDenormalized  
     Float fmaxDenormalized  

o  fmin
the smallest normalized non-zero value which can be represented by instances of this class;
should actually be sent to the instance,
because of IEEEFloat, which has instance-specific representation

Usage example(s):

     QDouble fmin -> 2.2250738585072e-308
     Float fmin   -> 2.2250738585072e-308

o  fminDenormalized
the smallest non-zero value which can be represented by instances of this class;
should actually be sent to the instance,
because of IEEEFloat, which has instance-specific representation

Usage example(s):

     QDouble fminDenormalized
     Float fminDenormalized

o  halfPi
return the constant pi/2 as quad precision double.
(returns approx. 200 bits of precision)

Usage example(s):

     self halfPi printfPrintString:'%.60f'
        '1.5707963267948966192313216916397514420985846996875529104874723'
     Wolfram says:
        '1.5707963267948966192313216916397514420985846996875529104874722961539082031431044993140174126710585339910740432566411533235469223047752911158626797040642405587251420513509692605527798223114744774651909822144054878329667230642378241168933915826356009545728243'

     (QDouble readFrom:'1.5707963267948966192313216916397514420985846996875529104874722961539082031431044993140174126710585339910740432566411533235469223047752911158626797040642405587251420513509692605527798223114744774651909822144054878329667230642378241168933915826356009545728243')
        printfPrintString:'%.60f'

o  infinity
(comment from inherited method)
return an instance of myself which represents positive infinity (for my instances).
Warning: do not compare equal against infinities;
instead, check using isFinite or isInfinite

o  ln10
return the constant natural logarithm log(10) as a qDouble.
(returns approx. 200 bits of precision)

Usage example(s):

     QDouble ln10 printfPrintString:'%.61f'
     self ln10 printfPrintString:'%.61f'
	-> '2.3025850929940456840179914546843642076011014886287729760333279'
     Wolfram says:
	    2.30258509299404568401799145468436420760110148862877297603332790096757260967735248023599720508959829834196778404228...

o  ln2
return the constant e as quad precision double.
(returns approx. 200 bits of precision)

Usage example(s):

     self ln2 printfPrintString:'%.61f'
	-> '0.6931471805599453094172321214581765680755001343602552541206800'
     Wolfram says:
	    0.69314718055994530941723212145817656807550013436025525412068000949339362196969471560586332699641868754200148102057...

o  negativeInfinity
(comment from inherited method)
return an instance of myself which represents negative infinity (for my instances).
Warning: do not compare equal against infinities;
instead, check using isFinite or isInfinite

o  pi
return the constant pi as quad precision double.
(returns approx. 200 bits of precision)

Usage example(s):

     self pi printfPrintString:'%.60f'
	  '3.141592653589793238462643383279502884197169399375105820974945'
     Wolfram says:
	   3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068

     (QDouble readFrom:'3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253')
     printfPrintString:'%.60f'

o  sqrt2
return sqrt(2) as a qDouble.
(returns approx. 200 bits of precision)

Usage example(s):

Sqrt2 := nil
     Number sqrt2Digits -> '1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927557999505011527820605714701095599716059702745345968620147285174186408891986095523292304843087143214508397626036279952514079896872533965463318'
     QDouble sqrt2      -> '1.41421356237309504880168872420969807856967187537694807317667974'

o  sqrt3
return sqrt(3) as a qDouble.
(returns approx. 200 bits of precision)

Usage example(s):

Sqrt3 := nil
     Number sqrt3Digits -> '1.73205080756887729352744634150587236694280525381038062805580697945193301690880003708114618675724857567562614141540670302996994509499895247881165551209437364852809323190230558206797482010108467492326501531234326690332288665067225466892183797122704713166036786'
     QDouble sqrt3      -> '1.73205080756887729352744634150587236694280525381038062805580698'

o  unity
return the neutral element for multiplication (1.0) as QDouble

Usage example(s):

     self unity

o  zero
return the neutral element for addition (0.0) as QDouble

Usage example(s):

     self zero

instance creation
o  basicNew
return a new quad-precision double - here we return 0.0
Notice that numbers are usually NOT created this way ...
It's implemented here to allow things like binary store & load
of floats. (but even this support will go away eventually, it's not
a good idea to store the bits of a float - the reader might have a
totally different representation - so floats should be
binary stored in a device independent format.

Usage example(s):

     self basicNew

o  d0: d0 d1: d1 d2: d2 d3: d3
return a new quad-precision double from individual double components

Usage example(s):

     self d0: 3.141592653589793116e+00
	  d1: 1.224646799147353207e-16
	  d2: -2.994769809718339666e-33
	  d3: 1.112454220863365282e-49

o  fromDoubleArray: aDoubleArray
return a new quad-precision double from coercing a double array

o  fromFloat: aFloat
return a new quad-precision double from coercing aFloat

Usage example(s):

     self fromFloat:1.0
     self fromFloat:0.2
     self fromFloat:(1.0 asLongFloat + (1.0 asLongFloat / (2 raisedTo:40)))
     self fromFloat:(1.0 asLongFloat + (1.0 asLongFloat / (2 raisedTo:53)))
     self fromFloat:(1.0 asLongFloat + (1.0 asLongFloat / (2 raisedTo:60)))

     Float fmax asQDouble           1.79769313486232e+308
     Float NaN asQDouble            nan
     Float infinity asQDouble       inf
     Float negativeInfinity asQDouble  -inf

o  fromInteger: anInteger
return a new quad-precision double from coercing anInteger

Usage example(s):

     self fromInteger:2
     self fromInteger:16rFFFFFFFF            -- 32bit 4294967295.0
     self fromInteger:16rFFFFFFFFFFFF        -- 48bit 281474976710655.0
     self fromInteger:16r7FFFFFFFFFFFF       -- 51bit 2.25179981368525e+15
     self fromInteger:16rFFFFFFFFFFFFF       -- 52bit 4.5035996273705e+15
     self fromInteger:16r1FFFFFFFFFFFFF      -- 53bit 9.00719925474099e+15
     self fromInteger:16r3FFFFFFFFFFFFF      -- 54bit 1.8014398509481983e+16
     self fromInteger:16rFFFFFFFFFFFFFF      -- 56bit 72057594037927935.0
     self fromInteger:16rFFFFFFFFFFFFFFF     -- 60bit 1152921504606846975.0
     self fromInteger:16r1FFFFFFFFFFFFFFF    -- 61bit 2305843009213693951.0
     self fromInteger:16r3FFFFFFFFFFFFFFF    -- 62bit 4611686018427387903.0
     self fromInteger:16r7FFFFFFFFFFFFFFF    -- 63bit 9223372036854775807.0
     self fromInteger:16rFFFFFFFFFFFFFFFF    -- 64bit 18446744073709551615.0 / 1.8446744073709551615e19
     self fromInteger:16r1FFFFFFFFFFFFFFFF   -- 65bit 36893488147419103231.0 / 3.6893488147419103231e19
     self fromInteger:16r3FFFFFFFFFFFFFFFF   -- 66bit 73786976294838206463.0 / 7.3786976294838206463e19
     self fromInteger:(10 raisedToInteger:1000)         -> INF
     self fromInteger:(10 raisedToInteger:1000) negated -> -INF
     self fromInteger:(MetaNumber NaN)                  -> nan

     self fromInteger:-16r7FFFFFFFFFFFFFFF    -- 63bit 9223372036854775807.0
     self fromInteger:-16rFFFFFFFFFFFFFFFF    -- 64bit 18446744073709551615.0 / 1.8446744073709551615e19
     self fromInteger:-16r1FFFFFFFFFFFFFFFF   -- 65bit 36893488147419103231.0 / 3.6893488147419103231e19
     self fromInteger:-16r3FFFFFFFFFFFFFFFF   -- 66bit 73786976294838206463.0 / 7.3786976294838206463e19

o  fromLongFloat: aLongFloat
return a new quad-precision double from coercing aLongFloat

Usage example(s):

     self fromLongFloat:1.0 asLongFloat
     1.0 asLongFloat asQDouble     1.

     (1.0 + 1e-16) - 1.0                -> 0.0
     (1.0 asLongFloat + 1e-16) - 1.0    -> 9.996344030316350881E-17

     (1.0 asLongFloat + 1e-16) asQDouble - 1.0
                                        -> 9.99634403031635016638603121124e-17
     LongFloat NaN asQDouble            NAN
     LongFloat infinity asQDouble       INF
     LongFloat negativeInfinity asQDouble  -INF
     (10 raisedTo:400) asLongFloat asQDouble

queries
o  defaultPrintPrecision
the default number of digits when printing

Usage example(s):

     ShortFloat defaultPrintPrecision   5
     Float defaultPrintPrecision        6
     LongFloat defaultPrintPrecision    8
     QDouble defaultPrintPrecision      10
     QuadFloat defaultPrintPrecision    9
     OctaFloat defaultPrintPrecision    11
     LargeFloat defaultPrintPrecision   12

o  defaultPrintfPrecision
the default number of digits when printing with printf's %f format

o  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):

     Float epsilon       -> 2.22044604925031e-16
     ShortFloat epsilon  -> 1.192093e-07
     LongFloat epsilon   -> 1.084202172485504434e-19
     QuadFloat epsilon   -> 1.92592994438723e-34
     QDouble epsilon     -> 7.77876909732643e-62 / (1.215432671457250056532e-63 read comment in precision)

o  isIEEEFormat

o  numBitsInExponent
answer the number of bits in the exponent.
I use regular IEEE doubles to store the value,
thus my exponent bits are the same as double's exponent bits

Usage example(s):

     1.0 asQDouble numBitsInExponent

o  numBitsInMantissa
answer the number of bits in the mantissa (the significant).
Here, a fake number is returned.
the hidden bit is not counted here

Usage example(s):

     1.0 asFloat numBitsInMantissa
     1.0 asShortFloat numBitsInMantissa
     1.0 asLongFloat numBitsInMantissa
     1.0 asQDouble numBitsInMantissa
     1.0 asQDouble class numBitsInMantissa

     Float numBitsInMantissa
     ShortFloat numBitsInMantissa
     QDouble numBitsInMantissa

o  precision
answer the precision (the number of bits in the mantissa) of my elements (in bits)
If my elments are IEEE floats, where only the fraction from the normalized mantissa is stored,
there will be a hidden bit and the mantissa will be actually represented by 1 more binary digits
(i.e. the number returned is 1 plus the actual number of bits stored)

Usage example(s):

^ (Float precision) * 4 - 3 + 1.

Usage example(s):

     ShortFloat precision  -> 24
     Float precision       -> 53
     LongFloat precision   -> 64
     QDouble precision     -> 204
     QuadFloat precision   -> 113
     OctaFloat precision   -> 237

     1.0 class numBitsInMantissa
     1.0 asShortFloat class numBitsInMantissa
     1.0 asLongFloat class numBitsInMantissa
     1.0 asQDouble class numBitsInMantissa

     Float numBitsInMantissa
     ShortFloat numBitsInMantissa
     QDouble numBitsInMantissa

o  radix
answer the radix of a QDouble's exponent
This is an IEEE float, which is represented as binary


Instance protocol:

arithmetic
o  * aNumber
return the product of the receiver and the argument, aNumber

Usage example(s):

     (QDouble fromFloat:1e20) * 2.0
     (QDouble fromFloat:1e20) * 1e20
     (QDouble fromFloat:1e20) * (QDouble fromFloat:1e20)
     ((QDouble fromFloat:1e20) * (QDouble fromFloat:2.0)) asDoubleArray
     ((QDouble fromFloat:1e-20) * (QDouble fromFloat:2.0)) asDoubleArray
     ((QDouble fromFloat:2.0) * (QDouble fromFloat:2.0)) asDoubleArray

o  + aNumber
return the sum of the receiver and the argument, aNumber

Usage example(s):

     ((QDouble fromFloat:1e20) + 1.0) asDoubleArray
     ((QDouble fromFloat:1e20) + (QDouble fromFloat:1.0)) asDoubleArray
     ((QDouble fromFloat:1e20) + (1.0 asQuadFloat)) asDoubleArray

o  - aNumber
return the sum of the receiver and the argument, aNumber

Usage example(s):

     (QDouble fromFloat:1e20) - 1.0
     ((QDouble fromFloat:1e20) - (QDouble fromFloat:1.0)) asDoubleArray
     (QDouble fromFloat:1e-20) asDoubleArray
     ((QDouble fromFloat:1e-20) - (QDouble fromFloat:1.0)) asDoubleArray
     ((QDouble fromFloat:2.0) - (QDouble fromFloat:1.0)) asDoubleArray

     ((QDouble fromFloat:2.0) - (QDouble fromFloat:1.0) + (QDouble fromFloat:1.0)) asDoubleArray
     ((QDouble fromFloat:1e-20) - (QDouble fromFloat:1.0) + (QDouble fromFloat:1.0)) asDoubleArray

o  / aNumber
return the quotient of the receiver and the argument, aNumber

Usage example(s):

     ((QDouble fromFloat:1e20) / (QDouble fromFloat:2.0)) asDoubleArray

     ((QDouble fromFloat:1.2345) / (QDouble fromFloat:10.0)) asDoubleArray
     ((QDouble fromFloat:1.2345) / 10.0) asDoubleArray
     ((QDouble fromFloat:1.2345) / 10) asDoubleArray

Usage example(s):

Modified (comment): / 13-10-2021 / 14:52:10 / cg

coercing & converting
o  asDoubleArray
(QDouble fromFloat:1.0) asDoubleArray
(1.0 asQDouble + 1e-40) asDoubleArray
(QDouble fromFloat:2.0) asDoubleArray
((QDouble fromFloat:2.e300) + 2.0) asDoubleArray

(2e300 + 2.0) - 2e300 -> 0.0 you loose with floats
((QDouble fromFloat:2e300) + 2.0) - 2e300 -> 2.0 better with QDouble
((2e300 asLargeFloatPrecision:500) + 2.0) - 2.e300 -> 2.0 better with QDouble

o  asFloat
return a Float (i.e. an IEEE double) with same value as the receiver.

Usage example(s):

     (QDouble fromFloat:1.0) asFloat  -> 1.0
     (QDouble fromFloat:2.0) asFloat  -> 2.0
     (2.0 asQDouble + 1e-14) asFloat  -> 2.00000000000001
     (2.0 + 1e-14) - 2.0              -> 1.02140518265514E-14
     (2.0 + 1e-15) - 2.0              -> 8.88178419700125E-16
     (2.0 + 1e-16) - 2.0              -> 0.0

o  asInteger
Does not raise an error for non-finite numbers (NaN or INF)

Usage example(s):

     Float NaN asInteger
     Float infinity asInteger
     Float negativeInfinity asInteger

     Float NaN asIntegerChecked
     Float infinity asIntegerChecked
     Float negativeInfinity asIntegerChecked

     QDouble NaN asInteger
     QDouble infinity asInteger
     QDouble negativeInfinity asInteger

o  asLargeFloat
(QDouble fromFloat:1.0) asLargeFloat -> 1.000000000000000000000000000000
(QDouble fromFloat:2.0) asLargeFloat -> 2.000000000000000000000000000000
(2.0 asQDouble + 1e-14) asLargeFloat -> 2.000000000000010214051826551440
(2.0 asLargeFloat + 1e-14) - 2.0 -> 0.000000000000010214051826551440
(2.0 + 1e-14) - 2.0 -> 1.02140518265514E-14
(2.0 asLargeFloat + 1e-14) - 2.0 -> 0.000000000000010214051826551440
(2.0 asLargeFloat + 1e-15) - 2.0 -> 0.000000000000000888178419700125
(2.0 asLargeFloat + 1e-16) - 2.0 -> 0.0
(2QL + 1QL-14) - 2QL -> 0.000000000000010000000000000000

o  asLargeFloatPrecision: precision
return a large float with (approximately) my value.
If the LargeFloat class is not present, a regular float is returned

Usage example(s):

     1.0 asQDouble asLargeFloatPrecision:10

o  asLongFloat
(QDouble fromFloat:1.0) asLongFloat -> 1.0
(QDouble fromFloat:2.0) asLongFloat -> 2.0
(2.0 asQDouble + 1e-14) asLongFloat -> 2.00000000000001
(2.0 asLongFloat + 1e-14) - 2.0 -> 1.00000303177028016E-14
(2.0 + 1e-14) - 2.0 -> 1.02140518265514E-14
(2.0 asLargeFloat + 1e-14) - 2.0 -> 0.000000000000010214051826551440
(2.0 asLargeFloat + 1e-15) - 2.0 -> 0.000000000000000888178419700125
(2.0 asLargeFloat + 1e-16) - 2.0 -> 0.0
(2QL + 1QL-14) - 2QL -> 0.000000000000010000000000000000

o  asQDouble
return a QDouble with same value as myself.

o  asQuadFloat
return a QuadFloat with same value as the receiver.
You may loose bits when doing this.

Usage example(s):

     (QDouble fromFloat:1.0) asQuadFloat    -> 1.0
     (QDouble fromFloat:2.0) asQuadFloat    -> 2.0
     (2.0 asQDouble + 1e-14) asQuadFloat    -> 2.00000000000001
     (2.0 asQuadFloat + 1e-14) - 2.0        -> 1.00000303177028016E-14
     (2.0  + 1e-14) - 2.0                   -> 1.02140518265514E-14
     (2.0 asQuadFloat + 1e-14) - 2.0       -> 0.000000000000010214051826551440
     (2.0 asQuadFloat + 1e-15) - 2.0       -> 0.000000000000000888178419700125
     (2.0 asQuadFloat + 1e-16) - 2.0       -> 0.0
     (2QL + 1QL-14) - 2QL                   -> 0.000000000000010000000000000000

     (QDouble NaN) asQuadFloat              -> nan
     (QDouble infinity) asQuadFloat         -> inf
     (QDouble negativeInfinity) asQuadFloat -> -inf

o  asTrueFraction
INF or NAN

Usage example(s):

     1e10 asTrueFraction        -> 10000000000
     1e20 asTrueFraction        -> 100000000000000000000
     (1e20 + 1) asTrueFraction  -> 100000000000000000000 ouch!

     1e10 asQDouble asTrueFraction       -> 10000000000
     1e20 asQDouble asTrueFraction       -> 100000000000000000000
     (1e20 asQDouble + 1) asTrueFraction -> 100000000000000000001

     (1e40 asQDouble + 1e20 + 1) asTrueFraction -> 10000000000000000303886028427003666890753
     (1e40 asQDouble + 1e20) asTrueFraction

o  exponent
extract a normalized float's (unbiased) 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 float's value is: mantissa * 2^exp

Usage example(s):

     1.0 asQDouble exponent     => 1
     1e20 asQDouble exponent    => 67
     QDouble NaN exponent -> error

o  generality
return the generality value - see ArithmeticValue>>retry:coercing:

o  mantissa
extract a normalized float's mantissa (as QDouble).
That is a float of the same type as the receiver,
such that:
(f mantissa) * (2 ^ f exponent) = f
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

Usage example(s):

     1.0 exponent        -> 1
     1.0 mantissa        -> 0.5
     12345.0 exponent    -> 14
     12345.0 mantissa    -> 0.75347900390625
     -1.0 exponent       -> 1
     -1.0 mantissa       -> -0.5
     -12345.0 exponent   -> 14
     -12345.0 mantissa   -> -0.75347900390625
     (1e40 + 1e-40) exponent   -> 133
     (1e40 + 1e-40) mantissa   -> 0.918354961579912

     0.0 asQDouble exponent        -> 0
     0.0 asQDouble mantissa        -> 0.5

     1.0 asQDouble exponent        -> 1
     1.0 asQDouble mantissa        -> 0.5
     1.0QD exponent                -> 1
     1.0QD mantissa                -> 0.5

     16QD exponent                 -> 5
     16QD mantissa                 -> 0.5

     9QD exponent                 -> 4
     9QD mantissa                 -> 0.5625

     -9QD exponent                 -> 4
     -9QD mantissa                 -> -0.5625

     12345.0 asQDouble exponent    -> 14
     12345.0 asQDouble mantissa    -> 0.75347900390625
     -1.0 asQDouble exponent       -> 1
     -1.0 asQDouble mantissa       -> -0.5
     -12345.0 asQDouble exponent   -> 14
     -12345.0 asQDouble mantissa   -> -0.75347900390625
     (1e40 + 1e-40) asQDouble exponent   -> 133
     (1e40 + 1e-40) asQDouble mantissa   -> 0.918354961579912

     self assert:(1.0 asQDouble mantissa * (2 raisedTo:1.0 asQDouble exponent)) = 1.0 asQDouble.
     self assert:(100.0 asQDouble mantissa * (2 raisedTo:100.0 asQDouble exponent)) = 100.0 asQDouble.
     self assert:(10e15 asQDouble mantissa * (2 raisedTo:10e15 asQDouble exponent)) = 10e15 asQDouble.
     self assert:(10e-15 asQDouble mantissa * (2 raisedTo:10e-15 asQDouble exponent)) = 10e-15 asQDouble.

comparing
o  < aNumber
return true, if the argument, aNumber is greater than the receiver

Usage example(s):

     1.0 < (1.0 + 1e-40)                     -> false
     1.0 < (1.0 asQDouble + 1e-40)           -> true
     1.0 asQDouble < (1.0 asQDouble + 1e-40) -> true

     1.0 asQDouble < 1.0 asQDouble           -> false
     1.0 asQDouble < 1.1 asQDouble           -> true
     1.0 asQDouble < 1.0                     -> false
     1.0  < 1.0 asQDouble                    -> false
     1.1 asQDouble < 1.0                     -> false
     1.1  < 1.0 asQDouble                    -> false
     1.0 asQDouble < 1.1                     -> true
     1.0  < 1.1 asQDouble                    -> true

     1.0 asQDouble < 1.0                     -> false
     0.9 asQDouble < 1.0                     -> true
     (1.0 asQDouble + 1e-20) < 1.0           -> false
     (1.0 asQDouble + 1e-20) < 1.1           -> true
     (1.0 asQDouble - 1e-20 + 1e-40) < 1.0   -> true

     1.0 asQDouble < 1                       -> false
     0.9 asQDouble < 1                       -> true

o  = aNumber
return true, if the argument, aNumber has the same value as the receiver

Usage example(s):

     1.0 asQDouble = 1.0 asQDouble      -> true
     1.0 asQDouble = 1.0                -> true
     1.0 asQDouble = 1.0 asShortFloat   -> true
     1.0 asQDouble = 1                  -> true

     1.0 asQDouble = 2.0 asQDouble      -> false
     1.0 asQDouble = 2.0                -> false
     1.0 asQDouble = 2.0 asShortFloat   -> false
     1.0 asQDouble = 2                  -> false

o  > aNumber
return true, if the argument, aNumber is greater than the receiver

double dispatching
o  differenceFromFloat: aFloat
aFloat - selfQDouble

o  differenceFromQDouble: aQDouble
aQDouble - selfQDouble

o  equalFromFloat: aFloat
aFloat = selfQDouble

o  equalFromQDouble: aQDouble
aQDouble = selfQDouble

o  lessFromFloat: aFloat
aFloat < selfQDouble

o  lessFromQDouble: aQDouble
aQDouble < selfQDouble
sent when aQDouble does not know how to compare to the receiver..
Return true if aQDouble < self

o  productFromFloat: aFloat
aFloat * selfQDouble

o  productFromInteger: anInteger
anInteger * selfQDouble

o  productFromQDouble: aQDouble
aQDouble * selfQDouble

o  quotientFromFloat: aFloat
Return the quotient of the argument, aFloat and the receiver.
Sent when aFloat does not know how to divide by the receiver.
Return aFloat / self

o  quotientFromQDouble: aQDouble
aQDouble / selfQDouble

Usage example(s):

     2.0 / (QDouble fromFloat:2.0)
     2.0 / (QDouble fromFloat:1.0)
     1e20 / (QDouble fromFloat:1.0)
     1e20 / (QDouble fromFloat:2.0)
     (2.0 / (QDouble fromFloat:1.0)) asFloat
     (1e20 / (QDouble fromFloat:1.0)) asFloat

     (QDouble fromFloat:2.0) / 2.0
     (QDouble fromFloat:1e20) / 2.0
     ((QDouble fromFloat:1.0) / 2.0) asFloat
     ((QDouble fromFloat:1e20 / 2.0)) asFloat

     ((1e20 + (QDouble fromFloat:1.0) + 1e-20) / 2.0) asDoubleArray

     ((QDouble fromFloat:10.0) quotientFromQDouble: (QDouble fromFloat:1.234)) asDoubleArray
     ((QDouble fromFloat:1.234) / (QDouble fromFloat:10.0)) asDoubleArray

o  sumFromFloat: aFloat
aFloat + selfQDouble

o  sumFromInteger: anInteger
anInteger + selfQDouble

o  sumFromQDouble: aQDouble
aQDouble + selfQDouble

inspecting
o  inspectorExtraAttributes
( an extension from the stx:libtool package )
extra (pseudo instvar) entries to be shown in an inspector.

mathematical functions
o  abs
return the absolute value of the receiver

Usage example(s):

     (0.0 asQDouble) abs
     (1.0 asQDouble) abs
     (-1.0 asQDouble) abs
     ((1e20 asQDouble) + (1.0 asQDouble)) negated abs asDoubleArray

o  cbrt
return the cubic root of the receiver

Usage example(s):

     27 asQDouble cbrt    -> 3.0
     27 cbrt              -> 3.0

o  cos
return the cosine of the receiver (interpreted as radians)

Usage example(s):

     1.0 cos                        0.5403023058681398
     (1.0 asQDouble) cos            0.54030230586813971740093660744297660373231042061792222767009726

     0.5 cos                        0.8775825618903728
     (0.5 asQDouble) cos            0.87758256189037271611628158260382965199164519710974405299761087

     0.001 cos                      0.9999995000000417
     (0.001 asQDouble) cos          0.99999950000004166666525696112433708989692354983014650257798907

     0.000001 cos                   0.9999999999995
     (0.000001 asQDouble) cos       0.99999999999950000000000004171191855483938397608693482028181867

     0.000000001 cos                1.0
     (0.000000001 asQDouble) cos    0.99999999999999999949999999999999993776007520888680831865015707

     1e-40 cos                      1.0
     (1e-40) asQDouble cos          1.0     (1.0 -5e-81 -4.22137477370303e-97 4.16666666666667e-162)

     1e-80 cos                      1.0
     (1e-80 asQDouble) cos          1.0   (1.0 -5e-161 3.28930062667053e-177 4.15015142506647e-322)

     1e-160 cos                     1.0
     (1e-160 asQDouble) cos         1.0  (1.0 -4.99994433591342e-321 0.0 0.0)

     1e-300 cos                     1.0
     (1e-300 asQDouble) cos         1.0  (1.0 0.0 0.0 0.0)

     0.0 cos                        1.0
     (0.0 asQDouble) cos            1.0

o  exp
return e raised to the power of the receiver

Usage example(s):

     1.0 exp
     (QDouble fromFloat:1.0) exp

     3.0 exp                 20.08553692318767
     3.0 asQDouble exp       20.0855369231876677409
     3.0 asOctaFloat exp     20.08553692318766774092

o  integerLog10
return the truncation of log10 of the receiver.
The same as (self log:10) floor (for positive logs).
Used eg. to find out the number of digits needed
to print a number/and for conversion to a LargeInteger.

Usage example(s):

     QDouble fmax log                 nan
     QDouble fmax d0 log              308.254715559917 
     QDouble fmax asLargeFloat log10  308.2547155599167434408130815850692389219714904949318632324

     QDouble fmax log10                      nan
     QDouble fmax d0 log10                   308.254715559917
     QDouble fmax integerLog10               308
     QDouble fmax asLargeFloat integerLog10  308

     QDouble fmin log                   -307.65265556858878150844115040843187335709005885427492921925687
     QDouble fmin integerLog10          -307               
     QDouble fmin d0 log                -307.652655568589
     QDouble fmin asLargeFloat log      -307.65265556858878150844115040843187335709005885427492921925

     QDouble fminDenormalized log10         -324.60909878882553993607722183831515182047975976376543480675132          
     QDouble fminDenormalized d0 log10      -323.306215343116             
     QDouble fminDenormalized integerLog10  -323             
     QDouble fminDenormalized asLargeFloat log10        -323.30621534311580356312282627877681038320678144778928338082
     QDouble fminDenormalized asLargeFloat integerLog10 -323
     4.94065645841247q-324  log10                       -323.3062153431158033

     QDouble fminDenormalized asLargeFloat asQDouble 4.94065645841247e-324
     QDouble fmin asLargeFloat asQDouble             2.2250738585072e-308
     QDouble fmaxDenormalized asLargeFloat asQDouble 4.4501477170144e-308
     QDouble fmax asLargeFloat asQDouble             1.79769313486231e+308

o  ldexp: exp
multiply the receiver by an integral power of 2.
I.e. return self * (2 ^ exp).
This is also the operation to reconstruct the original float from its
mantissa and exponent: (f mantissa ldexp:f exponent) = f

Usage example(s):

     |f| f := 1 asQDouble. (f mantissa ldexp:f exponent) -> 1.0
     |f| f := (1e40 asQDouble + 1e-40). (f mantissa ldexp:f exponent) -> (1e40 asQDouble + 1e-40)

     1.0 ldexp:16            -> 65536.0
     1.0 asQDouble ldexp:16  -> 65536.0
     1.0 ldexp:100           -> 1.26765060022823E+30
     1.0 asQDouble ldexp:100 -> 1.26765060022823E+30

o  ln
return the natural logarithm of myself.
Raises an exception, if the receiver is less or equal to zero.

Not sure if this is really faster than using a taylor right away:
the three exp-computations at the end are done in qDouble and are tailors themself...

o  negated
return the receiver negated

Usage example(s):

     (0.0 asQDouble) negated
     (1.0 asQDouble) negated
     ((1e20 asQDouble) + (1.0 asQDouble)) negated asDoubleArray

     (((QDouble fromFloat:1e20) + (QDouble fromFloat:1.0))
     + ((QDouble fromFloat:1e20) + (QDouble fromFloat:1.0))) asDoubleArray

o  nextFloat: n
answer the next float count places (ulps) after (or before if count is negative) myself.
One ulp is the distance to the next/previous representable float,
and this returns the float which is countUlps away from me.
Notice that ulps depend on the receiver: an ulp away from 1e100 has a different
value than 1 ulp away from 1e-100.
Thus, ulps are perfect for 'almost equal' comparisons.

Usage example(s):

     (1e20 + Float fmin) - 1e20   0.0

     (1.0 nextFloat:1)   - 1.0    2.22044604925031E-016
     (1e20 nextFloat:1)  - 1e20   16384.0
     (1e-20 nextFloat:1) - 1e-20  1.50463276905253E-036

     ((QDouble fromFloat:1.0) nextFloat:1) - (QDouble fromFloat:1.0)
     ((QDouble fromFloat:1.0) + QDouble fmin) - (QDouble fromFloat:1.0)
     ((QDouble fromFloat:1e20) nextFloat:1) - (QDouble fromFloat:1e20)
     ((QDouble fromFloat:1e-20) nextFloat:1) - (QDouble fromFloat:1e-20)

     (1.0 + Float fmin)  - 1.0
     (1e20 + Float fmin) - 1e20
     (1e-20 + Float fmin) - 1e-20

o  raisedToInteger: n
return the receiver raised to an integer exp.
The caller must ensure that the arg is actually an integer

Usage example(s):

     (4.0 ) raisedToInteger:4
     (4.0 asQDouble) raisedToInteger:4
     (10.0 asQDouble) raisedToInteger:10
     (10.0000000000001 asQDouble) raisedToInteger:10  -> 1.00000000000009947598300641847898399518914650009505862356046819e10
     10.0000000000001 raisedToInteger:10

o  sin
return the sine of the receiver (interpreted as radians)

Usage example(s):

     1.0 sin                      0.8414709848078965
     1.0 asQDouble sin            0.84147098480789650665250232163029899962256306079837106567275171

     0.0 sin                      0.0
     0.0 asQDouble sin            0.0

     Float pi sin                 1.224646799147353e-16
     QDouble pi sin               -0.0

o  sqrt
Return the square root of the receiver

Usage example(s):

     (4.0 asQDouble) sqrt      2.0
     (2.0 asQDouble) sqrt      1.4142135624
			       1.41421356237309504880168872420969807856967187537694807317667974
     wolfram:
			       1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927557999505011527820605714701095599716059702745345968620147285174186408891986095523292304843087143214508397626036279952514079896872533965463318088296406206152583523950547457502877599617298355752203375318570113543746034084988471603868999706990048150305440277903164542478230684929369186215805784631115966687130130156185689872372352885092648612494
     (1e20 asQDouble) sqrt     1.0e10
     (-4.0 asQDouble) sqrt                          -> error
     Number trapImaginary:[ (-4.0 asQDouble) sqrt ] -> (0+2.0i)

o  squared
return receiver * receiver

Usage example(s):

     (QDouble fromFloat:4.0) squared
     (1e20 + (QDouble fromFloat:1.0)) squared

o  tan
return the tangens of the receiver (interpreted as radians)

Usage example(s):

     1.0 tan
     (QDouble fromFloat:1.0) tan

printing & storing
o  digitsWithPrecision: precision
generate digits and exponent.
if precision is >0, that many digits are generated.
If it is 0 the required number of digits is generated
(but never more than the decimalPrecision, which is 65)

** This is an obsolete interface - do not use it (it may vanish in future versions) **

o  printOn: aStream
return a printed representation of the receiver.

Notice:
this code was adapted from an ugly piece of c++ code,
which was obviously hacked.
It does need a rework.
As an alternative, use the printf functions, which should also deal wth QDoubles

o  printOn: aStream precision: precisionIn width: width fixed: fixed showPositive: showPositive uppercase: uppercase fillChar: fillChar
return a printed representation of the receiver.
This is a parametrized entry, which can be used by printf-like functions.
Notice:
this code was adapted from an ugly piece of c++ code,
which was obviously hacked.
It does need a rework.
As an alternative, use the printf functions, which should also deal wth QDoubles


** This is an obsolete interface - do not use it (it may vanish in future versions) **

o  round_string_qd: str at: precisionIn offset: offsetIn

** This is an obsolete interface - do not use it (it may vanish in future versions) **

private
o  nintAsFloat
return the receiver truncated towards negative infinity

o  renorm
destructive renormalization

Usage example(s):

     (QDouble fromFloat:1.0) renorm

private accessing
o  d0
the most significant (and highest valued) 53 bits of precision

o  d1
the next most significant (and next highest valued) 53 bits of precision

o  d2

o  d3
the least significant (and smallest valued) 53 bits of precision

testing
o  isFinite
return true, if the receiver is a finite float (not NaN and not +/-INF)

Usage example(s):

     0.0 asQDouble isFinite         -> true
     1.0 asQDouble isFinite         -> true
     Float NaN asQDouble isFinite   -> false
     Float infinity asQDouble isFinite   -> false
     Float negativeInfinity asQDouble isFinite  -> false
     Float posiiveInfinity asQDouble isFinite   -> false

o  isInfinite
return true, if the receiver is an infinite float (+Inf or -Inf).

o  isNaN
return true, if the receiver is an invalid float (NaN - not a number)

Usage example(s):

^ self d0 isNaN

Usage example(s):

     0.0 asQDouble isNaN         -> false
     1.0 asQDouble isNaN         -> false
     Float NaN asQDouble isNaN   -> true

o  isZero
return true, if the receiver is zero

Usage example(s):

     0.0 asQDouble isZero
     1e-100 asQDouble isZero

o  negative
return true if the receiver is negative (< 0).

Usage example(s):

^ self d0 negative

Usage example(s):

     0.0 asQDouble negative
     1.0 asQDouble negative
     -1.0 asQDouble negative

     Float positiveInfinity asQDouble negative  -> false
     Float negativeInfinity asQDouble negative  -> true
     Float NaN asQDouble negative               -> false
     0.0 asQDouble negative                     -> false
     0.0 negated asQDouble negative             -> false
     0.0 negated asQDouble isNegativeZero       -> true

o  positive
return true, if the receiver is greater or equal to zero (not negative)

Usage example(s):

^ self d0 positive

Usage example(s):

     1.0 asQDouble positive               -> true
     0.0 asQDouble positive               -> true
     -1.0 asQDouble positive              -> false
     (1.0 asQDouble + 1e-100) positive    -> true
     (0.0 asQDouble + 1e-100) positive    -> true
     (0.0 asQDouble - 1e-100) positive    -> false

o  sign
return the sign of the receiver (-1, 0 or 1)

Usage example(s):

^ self d0 sign

Usage example(s):

     Float nan sign
     QDouble nan sign
     QDouble infinity sign
     QDouble infinity negated sign
     0 asQDouble sign
     1 asQDouble sign
     -1 asQDouble sign

o  strictlyPositive
return true, if the receiver is greater than zero (not negative or zero)

Usage example(s):

     1.0 asQDouble strictlyPositive               -> true
     0.0 asQDouble strictlyPositive               -> false
     -1.0 asQDouble strictlyPositive              -> false
     (1.0 asQDouble + 1e-100) strictlyPositive    -> true
     (0.0 asQDouble + 1e-100) strictlyPositive    -> true
     (0.0 asQDouble - 1e-100) strictlyPositive    -> false

truncation & rounding
o  ceiling
return the smallest integer which is greater or equal to the receiver.

Usage example(s):

     (4.0 asQDouble) ceiling          -> 4
     (4.1 asQDouble) ceiling          -> 5
     (0.1 asQDouble) ceiling          -> 1
     (0.1 + (1.0 asQDouble)) ceiling  -> 2
     (1e20 + (1.0 asQDouble)) ceiling -> 100000000000000000001

     (1.5 asQDouble) ceiling          -> 2
     (0.5 asQDouble) ceiling          -> 1
     (-0.5 asQDouble) ceiling         -> 0
     (-1.5 asQDouble) ceiling         -> -1

o  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.

Usage example(s):

     (4.0 asQDouble) ceilingAsFloat          -> 4.0
     (4.1 asQDouble) ceilingAsFloat          -> 5.0
     (0.1 asQDouble) ceilingAsFloat          -> 1.0
     (0.1 + (1.0 asQDouble)) ceilingAsFloat  -> 2.0
     (1e20 + (1.0 asQDouble)) ceilingAsFloat -> 1.00000000000000000001e20

     (1.5 asQDouble) ceilingAsFloat          -> 2.0
     (0.5 asQDouble) ceilingAsFloat          -> 1.0
     (-0.5 asQDouble) ceilingAsFloat         -> -0.0
     (-1.5 asQDouble) ceilingAsFloat         -> -1.0

o  floor
return the receiver truncated towards negative infinity

Usage example(s):

     (4.0 asQDouble) floor                       -> 4
     (4.1 asQDouble) floor                       -> 4
     (0.1 asQDouble) floor                       -> 0
     (0.1 + (1.0 asQDouble)) floor               -> 1
     (1e20 + (1.0 asQDouble)) floor              -> 100000000000000000001
     (1e20 asQDouble + 1e-20 asQDouble) floor    -> 100000000000000000000
     (1e100 asQDouble + 0.5 asQDouble) floor

     (1.5 asQDouble) floor      -> 1
     (0.5 asQDouble) floor      -> 0
     (-0.5 asQDouble) floor     -> -1
     (-1.5 asQDouble) floor     -> -2

o  floorAsFloat
return the receiver truncated towards negative infinity.
This is much like #floor, 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.

o  rounded
return the receiver rounded to the nearest integer

Usage example(s):

     (1e100 asInteger)
     (1e100 asQDouble) roundedAsFloat 1e+100
     (1e100 asQDouble) rounded
     (1e100 asQDouble + 0.5 asQDouble) roundedAsFloat
     (1e100 asQDouble + 0.5 asQDouble) rounded

     (QDouble fromFloat:4.0) rounded          -> 4
     (QDouble fromFloat:4.6) rounded          -> 5
     (QDouble fromFloat:4.50000001) rounded   -> 5
     (QDouble fromFloat:4.5) rounded          -> 5
     (QDouble fromFloat:4.49999999) rounded   -> 4
     (QDouble fromFloat:4.4) rounded          -> 4
     (QDouble fromFloat:4.1) rounded          -> 4
     (QDouble fromFloat:0.1) rounded          -> 0
     (QDouble fromFloat:0.5) rounded          -> 1
     (QDouble fromFloat:0.49999) rounded      -> 0
     (QDouble fromFloat:0.50001) rounded      -> 1
     (QDouble fromFloat:0.4) rounded          -> 0

     (QDouble fromFloat:-4.0) rounded
     (QDouble fromFloat:-4.6) rounded
     (QDouble fromFloat:-4.4) rounded
     (QDouble fromFloat:-4.499999999) rounded
     (QDouble fromFloat:-4.5) rounded
     (QDouble fromFloat:-4.5000000001) rounded
     (QDouble fromFloat:-4.1) rounded
     (QDouble fromFloat:-0.1) rounded
     (QDouble fromFloat:-0.5) rounded
     (QDouble fromFloat:-0.4) rounded

o  roundedAsFloat
return the receiver rounded to the nearest integer.
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.

Usage example(s):

     (QDouble fromFloat:4.0) roundedAsFloat
     (QDouble fromFloat:4.6) roundedAsFloat
     (QDouble fromFloat:4.50000001) roundedAsFloat
     (QDouble fromFloat:4.5) roundedAsFloat
     (QDouble fromFloat:4.49999999) roundedAsFloat
     (QDouble fromFloat:4.4) roundedAsFloat
     (QDouble fromFloat:4.1) roundedAsFloat
     (QDouble fromFloat:0.1) roundedAsFloat
     (QDouble fromFloat:0.5) roundedAsFloat
     (QDouble fromFloat:0.49999) roundedAsFloat
     (QDouble fromFloat:0.4) roundedAsFloat

     (QDouble fromFloat:-4.0) roundedAsFloat
     (QDouble fromFloat:-4.6) roundedAsFloat
     (QDouble fromFloat:-4.4) roundedAsFloat
     (QDouble fromFloat:-4.499999999) roundedAsFloat
     (QDouble fromFloat:-4.5) roundedAsFloat
     (QDouble fromFloat:-4.5000000001) roundedAsFloat
     (QDouble fromFloat:-4.1) roundedAsFloat
     (QDouble fromFloat:-0.1) roundedAsFloat
     (QDouble fromFloat:-0.5) roundedAsFloat
     (QDouble fromFloat:-0.4) roundedAsFloat


Examples:


Floats, LongFloats suffer from loosing bits:

   (Float readFrom:'0.3333333333333333333333333333333333333333333333333333333333')
  -(Float readFrom:'0.333333333333333333333333333333333333333333333333333333333')
      -> 0.0

     (Float readFrom:'0.3333333333333333333333333333333333333333333333333333333333')
   = (Float readFrom:'0.333333333333333333333333333333333333333333333333333333333')
      -> true

     (Float readFrom:'0.33333333333333333333333333333333333333333333333333333333333333333333')
   = (Float readFrom:'0.3333333333333333333333333333333333333333333333333333333333333333333')
      -> true
1000 0110 1000 0101 1000 0101 1000 0101 1000 0101 1000 0101 1101 0101 0011 1111
     (Float readFrom:'0.3333333333333333333333333333333333333333333333333333333333')
   = (Float readFrom:'0.3333333333333333333333333333333333333333333333333333333333333333333')

   (LongFloat readFrom:'0.3333333333333333333333333333333333333333333333333333333333')
  -(LongFloat readFrom:'0.333333333333333333333333333333333333333333333333333333333')
      -> 0.0

    (LongFloat readFrom:'0.3333333333333333333333333333333333333333333333333333333333')
  = (LongFloat readFrom:'0.333333333333333333333333333333333333333333333333333333333')
      -> 0.0

 (QDouble readFrom:'0.3333333333333333333333333333333333333333333333333333333333')
-(QDouble readFrom:'0.333333333333333333333333333333333333333333333333333333333')

 (QDouble readFrom:'0.33333333333333333333333333333333333333333333333333333333333')
-(QDouble readFrom:'0.3333333333333333333333333333333333333333333333333333333333')


 (QDouble readFrom:'0.33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333')
-(QDouble readFrom:'0.3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333')


ST/X 7.7.0.0; WebServer 1.702 at 20f6060372b9.unknown:8081; Wed, 08 May 2024 03:34:47 GMT