--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/QDouble.st Tue Jun 13 09:01:30 2017 +0200
@@ -0,0 +1,1539 @@
+"
+ 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.
+"
+"{ Package: 'stx:libbasic2' }"
+
+"{ NameSpace: Smalltalk }"
+
+LimitedPrecisionReal variableByteSubclass:#QDouble
+ instanceVariableNames:''
+ classVariableNames:'DefaultPrintFormat QDoubleZero QDoubleOne Pi E Ln2 Ln10 Epsilon'
+ poolDictionaries:''
+ category:'Magnitude-Numbers'
+!
+
+!QDouble primitiveDefinitions!
+%{
+#include <stdio.h>
+#include <errno.h>
+
+#define __USE_ISOC9X 1
+#define __USE_ISOC99 1
+#include <math.h>
+
+/*
+ * on some systems, errno is a macro ... check for it here
+ */
+#ifndef errno
+ extern errno;
+#endif
+
+#if !defined (__win32__)
+# include <locale.h>
+#endif
+
+#if defined (__aix__)
+# include <float.h>
+#endif
+
+#if defined(__irix__) || defined(__solaris__) || defined(__sunos__)
+# include <nan.h>
+#endif
+
+#if defined(__linux__)
+# ifndef NAN
+# include <bits/nan.h>
+# endif
+#endif
+
+struct qd_real {
+ double x[4]; /* The Components. */
+};
+
+struct __quadDoubleStruct {
+ STX_OBJ_HEADER
+#ifdef __NEED_DOUBLE_ALIGN
+ __FILLTYPE_DOUBLE f_filler;
+#endif
+ double d_quadDoubleValue[4];
+};
+
+#define __QuadDoubleInstPtr(obj) ((struct __quadDoubleStruct *)(__objPtr(obj)))
+
+#ifndef __isQuadDouble
+# define __isQuadDouble(o) \
+ (__Class(o) == @global(QuadDouble))
+#endif
+
+#ifndef __qIsQuadDouble
+# define __qIsQuadDouble(o) \
+ (__qClass(o) == @global(QuadDouble))
+#endif
+
+#define __qNew_qdReal(newQD, d0,d1,d2,d3) { \
+ __qNew(newQD, sizeof(struct __quadDoubleStruct)); \
+ __stx_setClass(newQD, QDouble); \
+ __QuadDoubleInstPtr(newQD)->d_quadDoubleValue[0] = d0; \
+ __QuadDoubleInstPtr(newQD)->d_quadDoubleValue[1] = d1; \
+ __QuadDoubleInstPtr(newQD)->d_quadDoubleValue[2] = d2; \
+ __QuadDoubleInstPtr(newQD)->d_quadDoubleValue[3] = d3; \
+}
+
+// qd_real(c0, c1, c2, c3);
+
+#define _QD_SPLITTER 134217729.0 // = 2^27 + 1
+#define _QD_SPLIT_THRESH 6.69692879491417e+299 // = 2^996
+
+#define m_quick_two_sum(rslt, a, b, err) {\
+ double s = a + b;\
+ err = b - (s - a);\
+ rslt = s; \
+}
+
+#define m_two_sum(rslt, a, b, err) {\
+ double s = a + b;\
+ double bb = s - a;\
+ err = (a - (s - bb)) + (b - bb);\
+ rslt = s;\
+}
+
+#define m_three_sum(a, b, c) { \
+ double t1, t2, t3; \
+ m_two_sum(t1, a, b, t2); \
+ m_two_sum(a, c, t1, t3); \
+ m_two_sum(b, t2, t3, c); \
+}
+
+#define m_three_sum2(a, b, c) {\
+ double t1, t2, t3;\
+ m_two_sum(t1, a, b, t2);\
+ m_two_sum(a, c, t1, t3);\
+ b = t2 + t3;\
+}
+
+#ifndef QD_FMS
+
+/* Computes high word and lo word of a */
+#define m_split(a, hi, lo) {\
+ double temp;\
+ if (a > _QD_SPLIT_THRESH || a < -_QD_SPLIT_THRESH) {\
+ a *= 3.7252902984619140625e-09;\
+ temp = _QD_SPLITTER * a;\
+ hi = temp - (temp - a);\
+ lo = a - hi;\
+ hi *= 268435456.0;\
+ lo *= 268435456.0;\
+ } else {\
+ temp = _QD_SPLITTER * a;\
+ hi = temp - (temp - a);\
+ lo = a - hi;\
+ }\
+}
+
+#endif
+
+
+#ifdef QD_FMS
+
+/* Computes fl(a*b) and err(a*b). */
+
+#define m_two_prod(rslt, a, b, err) {\
+ double p = a * b;\
+ err = QD_FMS(a, b, p);\
+ rslt = p; \
+}
+
+#else
+
+#define m_two_prod(rslt, a, b, err) {\
+ double a_hi, a_lo, b_hi, b_lo;\
+ double p = a * b;\
+ m_split(a, a_hi, a_lo);\
+ m_split(b, b_hi, b_lo);\
+ err = ((a_hi * b_hi - p) + a_hi * b_lo + a_lo * b_hi) + a_lo * b_lo;\
+ rslt = p; \
+}
+
+#endif
+
+#ifdef QD_FMS
+
+#define m_two_sqr(rslt, a, err) {\
+ double p = a * a;\
+ err = QD_FMS(a, a, p);\
+ rslt = p;\
+}
+
+#else
+
+#define m_two_sqr(rslt, a, err) {\
+ double hi, lo;\
+ double q = a * a;\
+ m_split(a, hi, lo);\
+ err = ((hi * hi - q) + 2.0 * hi * lo) + lo * lo;\
+ rslt = q;\
+}
+
+#endif
+
+#define m_renorm4(c0, c1, c2, c3) {\
+ double s0, s1, s2 = 0.0, s3 = 0.0;\
+\
+ if (! isinf(c0)) { \
+\
+ m_quick_two_sum(s0, c2, c3, c3);\
+ m_quick_two_sum(s0, c1, s0, c2);\
+ m_quick_two_sum(c0, c0, s0, c1);\
+\
+ s0 = c0;\
+ s1 = c1;\
+ if (s1 != 0.0) {\
+ m_quick_two_sum(s1, s1, c2, s2);\
+ if (s2 != 0.0) {\
+ m_quick_two_sum(s2, s2, c3, s3);\
+ } else {\
+ m_quick_two_sum(s1, s1, c3, s2);\
+ }\
+ } else {\
+ m_quick_two_sum(s0, s0, c2, s1);\
+ if (s1 != 0.0) {\
+ m_quick_two_sum(s1, s1, c3, s2);\
+ } else {\
+ m_quick_two_sum(s0, s0, c3, s1);\
+ }\
+ }\
+\
+ c0 = s0;\
+ c1 = s1;\
+ c2 = s2;\
+ c3 = s3;\
+ }\
+}
+
+#define m_renorm5(c0, c1, c2, c3, c4) { \
+ double s0, s1, s2 = 0.0, s3 = 0.0; \
+\
+ if (! isinf(c0)) { \
+ m_two_sum(s0, c3, c4, c4); \
+ m_quick_two_sum(s0, c2, s0, c3); \
+ m_quick_two_sum(s0, c1, s0, c2); \
+ m_quick_two_sum(c0, c0, s0, c1); \
+\
+ s0 = c0; \
+ s1 = c1; \
+\
+ m_two_sum(s0, c0, c1, s1); \
+ if (s1 != 0.0) { \
+ m_quick_two_sum(s1, s1, c2, s2); \
+ if (s2 != 0.0) { \
+ m_quick_two_sum(s2 ,s2, c3, s3); \
+ if (s3 != 0.0) {\
+ s3 += c4; \
+ } else {\
+ s2 += c4;\
+ }\
+ } else { \
+ m_quick_two_sum(s1, s1, c3, s2); \
+ if (s2 != 0.0) {\
+ m_quick_two_sum(s2, s2, c4, s3); \
+ } else { \
+ m_quick_two_sum(s1, s1, c4, s2); \
+ } \
+ } \
+ } else { \
+ m_quick_two_sum(s0,s0, c2, s1); \
+ if (s1 != 0.0) { \
+ m_quick_two_sum(s1,s1, c3, s2); \
+ if (s2 != 0.0) {\
+ m_quick_two_sum(s2,s2, c4, s3); \
+ } else { \
+ m_quick_two_sum(s1 ,s1, c4, s2); \
+ } \
+ } else { \
+ m_quick_two_sum(s0,s0, c3, s1); \
+ if (s1 != 0.0) { \
+ m_quick_two_sum(s1,s1, c4, s2); \
+ } else { \
+ m_quick_two_sum(s0,s0, c4, s1); \
+ } \
+ } \
+ } \
+ \
+ c0 = s0; \
+ c1 = s1; \
+ c2 = s2; \
+ c3 = s3; \
+ } \
+}
+
+%}
+! !
+
+!QDouble primitiveFunctions!
+%{
+
+/*********** Basic Functions ************/
+/* Computes fl(a+b) and err(a+b). Assumes |a| >= |b|. */
+inline double
+quick_two_sum(double a, double b, double *errPtr) {
+ double s = a + b;
+ *errPtr = b - (s - a);
+ return s;
+}
+
+/* Computes fl(a-b) and err(a-b). Assumes |a| >= |b| */
+inline double
+quick_two_diff(double a, double b, double *errPtr) {
+ double s = a - b;
+ *errPtr = (a - s) - b;
+ return s;
+}
+
+/* Computes fl(a+b) and err(a+b). */
+inline double
+two_sum(double a, double b, double *errPtr) {
+ double s = a + b;
+ double bb = s - a;
+ *errPtr = (a - (s - bb)) + (b - bb);
+ return s;
+}
+
+/* Computes fl(a-b) and err(a-b). */
+inline double
+two_diff(double a, double b, double *errPtr) {
+ double s = a - b;
+ double bb = s - a;
+ *errPtr = (a - (s - bb)) - (b + bb);
+ return s;
+}
+
+#ifndef QD_FMS
+/* Computes high word and lo word of a */
+inline void
+split(double a, double *hiPtr, double *loPtr) {
+ double temp;
+ if (a > _QD_SPLIT_THRESH || a < -_QD_SPLIT_THRESH) {
+ a *= 3.7252902984619140625e-09; // 2^-28
+ temp = _QD_SPLITTER * a;
+ *hiPtr = temp - (temp - a);
+ *loPtr = a - *hiPtr;
+ *hiPtr *= 268435456.0; // 2^28
+ *loPtr *= 268435456.0; // 2^28
+ } else {
+ temp = _QD_SPLITTER * a;
+ *hiPtr = temp - (temp - a);
+ *loPtr = a - *hiPtr;
+ }
+}
+#endif
+
+/* Computes fl(a*b) and err(a*b). */
+inline double
+two_prod(double a, double b, double *errPtr) {
+#ifdef QD_FMS
+ double p = a * b;
+ *errPtr = QD_FMS(a, b, p);
+ return p;
+#else
+ double a_hi, a_lo, b_hi, b_lo;
+ double p = a * b;
+ split(a, &a_hi, &a_lo);
+ split(b, &b_hi, &b_lo);
+ *errPtr = ((a_hi * b_hi - p) + a_hi * b_lo + a_lo * b_hi) + a_lo * b_lo;
+ return p;
+#endif
+}
+
+/* Computes fl(a*a) and err(a*a). Faster than the above method. */
+inline double
+two_sqr(double a, double *errPtr) {
+#ifdef QD_FMS
+ double p = a * a;
+ *errPtr = QD_FMS(a, a, p);
+ return p;
+#else
+ double hi, lo;
+ double q = a * a;
+ split(a, &hi, &lo);
+ *errPtr = ((hi * hi - q) + 2.0 * hi * lo) + lo * lo;
+ return q;
+#endif
+}
+
+/* Computes the nearest integer to d. */
+inline double
+nint(double d) {
+ if (d == floor(d))
+ return d;
+ return floor(d + 0.5);
+}
+
+/* Computes the truncated integer. */
+inline double
+aint(double d) {
+ return (d >= 0.0) ? floor(d) : ceil(d);
+}
+
+inline void
+renorm4(double *c0Ptr, double *c1Ptr, double *c2Ptr, double *c3Ptr) {
+ double s0, s1, s2 = 0.0, s3 = 0.0;
+ double c0 = *c0Ptr;
+
+ if (isinf(c0)) return;
+
+ s0 = quick_two_sum(*c2Ptr, *c3Ptr, c3Ptr);
+ s0 = quick_two_sum(*c1Ptr, s0, c2Ptr);
+ c0 = quick_two_sum(c0, s0, c1Ptr);
+
+ s0 = c0;
+ s1 = *c1Ptr;
+ if (s1 != 0.0) {
+ s1 = quick_two_sum(s1, *c2Ptr, &s2);
+ if (s2 != 0.0)
+ s2 = quick_two_sum(s2, *c3Ptr, &s3);
+ else
+ s1 = quick_two_sum(s1, *c3Ptr, &s2);
+ } else {
+ s0 = quick_two_sum(s0, *c2Ptr, &s1);
+ if (s1 != 0.0)
+ s1 = quick_two_sum(s1, *c3Ptr, &s2);
+ else
+ s0 = quick_two_sum(s0, *c3Ptr, &s1);
+ }
+
+ *c0Ptr = s0;
+ *c1Ptr = s1;
+ *c2Ptr = s2;
+ *c3Ptr = s3;
+}
+
+inline void
+renorm5(double *c0Ptr, double *c1Ptr, double *c2Ptr, double *c3Ptr, double *c4Ptr) {
+ double s0, s1, s2 = 0.0, s3 = 0.0;
+
+ if (isinf(*c0Ptr)) return;
+
+ s0 = quick_two_sum(*c3Ptr, *c4Ptr, c4Ptr);
+ s0 = quick_two_sum(*c2Ptr, s0, c3Ptr);
+ s0 = quick_two_sum(*c1Ptr, s0, c2Ptr);
+ *c0Ptr = quick_two_sum(*c0Ptr, s0, c1Ptr);
+
+ s0 = *c0Ptr;
+ s1 = *c1Ptr;
+
+ s0 = quick_two_sum(*c0Ptr, *c1Ptr, &s1);
+ if (s1 != 0.0) {
+ s1 = quick_two_sum(s1, *c2Ptr, &s2);
+ if (s2 != 0.0) {
+ s2 =quick_two_sum(s2, *c3Ptr, &s3);
+ if (s3 != 0.0)
+ s3 += *c4Ptr;
+ else
+ s2 += *c4Ptr;
+ } else {
+ s1 = quick_two_sum(s1, *c3Ptr, &s2);
+ if (s2 != 0.0)
+ s2 = quick_two_sum(s2, *c4Ptr, &s3);
+ else
+ s1 = quick_two_sum(s1, *c4Ptr, &s2);
+ }
+ } else {
+ s0 = quick_two_sum(s0, *c2Ptr, &s1);
+ if (s1 != 0.0) {
+ s1 = quick_two_sum(s1, *c3Ptr, &s2);
+ if (s2 != 0.0)
+ s2 = quick_two_sum(s2, *c4Ptr, &s3);
+ else
+ s1 = quick_two_sum(s1, *c4Ptr, &s2);
+ } else {
+ s0 = quick_two_sum(s0, *c3Ptr, &s1);
+ if (s1 != 0.0)
+ s1 = quick_two_sum(s1, *c4Ptr, &s2);
+ else
+ s0 = quick_two_sum(s0, *c4Ptr, &s1);
+ }
+ }
+
+ *c0Ptr = s0;
+ *c1Ptr = s1;
+ *c2Ptr = s2;
+ *c3Ptr = s3;
+}
+
+inline void
+three_sum(double *aPtr, double *bPtr, double *cPtr) {
+ double t1, t2, t3;
+ t1 = two_sum(*aPtr, *bPtr, &t2);
+ *aPtr = two_sum(*cPtr, t1, &t3);
+ *bPtr = two_sum(t2, t3, cPtr);
+}
+
+inline void three_sum2(double *aPtr, double *bPtr, double *cPtr) {
+ double t1, t2, t3;
+ t1 = two_sum(*aPtr, *bPtr, &t2);
+ *aPtr = two_sum(*cPtr, t1, &t3);
+ *bPtr = t2 + t3;
+}
+
+
+#if 0
+/* These are provided to give consistent
+ interface for double with double-double and quad-double. */
+inline void
+sincosh(double t, double &sinh_t, double &cosh_t) {
+ sinh_t = sinh(t);
+ cosh_t = cosh(t);
+}
+
+inline double
+sqr(double t) {
+ return t * t;
+}
+
+inline double
+to_double(double a) {
+ return a;
+}
+
+inline int
+to_int(double a) {
+ return static_cast<int>(a);
+}
+#endif
+
+%}
+! !
+
+!QDouble class methodsFor:'documentation'!
+
+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.
+"
+!
+
+documentation
+"
+ QDoubles represent rational numbers with extended, but still limited precision.
+
+ In contrast to Floats (which use the C-compilers native 64bit 'double' format),
+ QDoubles give you 212 bit or approx. 64 decimal digits of precision.
+
+ Representation:
+ QDoubles use 4 IEEE doubles, each keeping 53 bits of precision.
+
+ Range and Precision of Storage Formats: see LimitedPrecisionReal >> documentation
+
+ [author:]
+ Claus Gittinger
+
+ [see also:]
+ Number
+ Float ShortFloat Fraction FixedPoint Integer Complex
+ FloatArray DoubleArray
+"
+! !
+
+!QDouble class methodsFor:'instance creation'!
+
+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."
+
+%{ /* NOCONTEXT */
+#ifdef __SCHTEAM__
+ ERROR("trying to instantiate a quad double");
+#else
+ OBJ newFloat;
+printf("xxx\n");
+ __qNew(newFloat, sizeof(struct __quadDoubleStruct));
+ __stx_setClass(newFloat, QDouble);
+ __QuadDoubleInstPtr(newFloat)->d_quadDoubleValue[0] = 0.0;
+ __QuadDoubleInstPtr(newFloat)->d_quadDoubleValue[1] = 0.0;
+ __QuadDoubleInstPtr(newFloat)->d_quadDoubleValue[2] = 0.0;
+ __QuadDoubleInstPtr(newFloat)->d_quadDoubleValue[3] = 0.0;
+ RETURN (newFloat);
+#endif /* not SCHTEAM */
+%}
+
+ "
+ self basicNew
+ "
+
+ "Created: / 12-06-2017 / 16:00:38 / cg"
+!
+
+d0:d0 d1:d1 d2:d2 d3:d3
+ "return a new quad-precision double from individual double components"
+
+%{ /* NOCONTEXT */
+#ifdef __SCHTEAM__
+ ERROR("trying to instantiate a quad double");
+#else
+ OBJ newQD;
+
+ if (__isFloatLike(d0)
+ && __isFloatLike(d1)
+ && __isFloatLike(d2)
+ && __isFloatLike(d3)) {
+ __qNew_qdReal(newQD, __floatVal(d0), __floatVal(d1),
+ __floatVal(d2), __floatVal(d3));
+ RETURN (newQD);
+ }
+#endif
+%}.
+ self error:'invalid argument'
+
+ "
+ self d0: 3.141592653589793116e+00
+ d1: 1.224646799147353207e-16
+ d2: -2.994769809718339666e-33
+ d3: 1.112454220863365282e-49
+ "
+
+ "Created: / 12-06-2017 / 20:17:14 / cg"
+!
+
+fromDoubleArray:aDoubleArray
+ "return a new quad-precision double from coercing a double array"
+
+%{ /* NOCONTEXT */
+#ifdef __SCHTEAM__
+ ERROR("trying to instantiate a quad double");
+#else
+ OBJ newQD;
+
+ if (__isDoubleArray(aDoubleArray)) {
+ __qNew_qdReal(newQD,
+ __DoubleArrayInstPtr(aDoubleArray)->d_element[0],
+ __DoubleArrayInstPtr(aDoubleArray)->d_element[1],
+ __DoubleArrayInstPtr(aDoubleArray)->d_element[2],
+ __DoubleArrayInstPtr(aDoubleArray)->d_element[3]);
+ RETURN (newQD);
+ }
+#endif
+%}.
+ self error:'invalid argument'
+
+ "
+ self fromDoubleArray(DoubleArray
+ with: 3.141592653589793116e+00
+ with: 1.224646799147353207e-16
+ with: -2.994769809718339666e-33
+ with: 1.112454220863365282e-49)
+ "
+
+ "Created: / 12-06-2017 / 18:25:32 / cg"
+!
+
+fromFloat:aFloat
+ "return a new quad-precision double from coercing aFloat"
+
+%{ /* NOCONTEXT */
+#ifdef __SCHTEAM__
+ ERROR("trying to instantiate a quad double");
+#else
+ double dVal;
+ OBJ newFloat;
+
+ if (__isFloatLike(aFloat)) {
+ dVal = __floatVal(aFloat);
+ } else if (__isShortFloat(aFloat)) {
+ dVal = __shortFloatVal(aFloat);
+ } else {
+ goto badArg;
+ }
+
+ __qNew(newFloat, sizeof(struct __quadDoubleStruct));
+ __stx_setClass(newFloat, QDouble);
+ __QuadDoubleInstPtr(newFloat)->d_quadDoubleValue[0] = dVal;
+ __QuadDoubleInstPtr(newFloat)->d_quadDoubleValue[1] = 0.0;
+ __QuadDoubleInstPtr(newFloat)->d_quadDoubleValue[2] = 0.0;
+ __QuadDoubleInstPtr(newFloat)->d_quadDoubleValue[3] = 0.0;
+ RETURN (newFloat);
+
+badArg: ;
+
+#endif
+%}.
+ self error:'invalid argument'
+
+ "
+ self fromFloat:1.0
+ "
+
+ "Created: / 12-06-2017 / 16:06:54 / cg"
+!
+
+fromInteger:anInteger
+ "return a new quad-precision double from coercing anInteger"
+
+%{ /* NOCONTEXT */
+#ifndef __SCHTEAM__
+ OBJ newFloat;
+
+ if (__isSmallInteger(anInteger)) {
+ __qNew(newFloat, sizeof(struct __quadDoubleStruct));
+ __stx_setClass(newFloat, QDouble);
+ __QuadDoubleInstPtr(newFloat)->d_quadDoubleValue[0] = (double)(__smallIntegerVal(anInteger));
+ __QuadDoubleInstPtr(newFloat)->d_quadDoubleValue[1] = 0.0;
+ __QuadDoubleInstPtr(newFloat)->d_quadDoubleValue[2] = 0.0;
+ __QuadDoubleInstPtr(newFloat)->d_quadDoubleValue[3] = 0.0;
+ RETURN (newFloat);
+ }
+#endif
+%}.
+ ^ super fromInteger:anInteger
+
+ "
+ self fromInteger:2
+ "
+
+ "Created: / 12-06-2017 / 16:10:10 / cg"
+! !
+
+!QDouble class methodsFor:'constants'!
+
+e
+ "return the constant e as quad precision double.
+ (returns approx. 212 bits of precision)"
+
+ E isNil ifTrue:[
+ E := self fromDoubleArray(DoubleArray
+ with: 2.718281828459045091e+00
+ with: 1.445646891729250158e-16
+ with: -2.127717108038176765e-33
+ with: 1.515630159841218954e-49)
+ ].
+ ^ E
+
+ "
+ self e
+ "
+
+ "Created: / 12-06-2017 / 18:29:36 / cg"
+!
+
+ln10
+ "return the constant e as quad precision double.
+ (returns approx. 212 bits of precision)"
+
+ Ln10 isNil ifTrue:[
+ Ln10 := self fromDoubleArray(DoubleArray
+ with: 2.302585092994045901e+00
+ with: -2.170756223382249351e-16
+ with: -9.984262454465776570e-33
+ with: -4.023357454450206379e-49)
+ ].
+ ^ Ln10
+
+ "
+ self ln10
+ "
+
+ "Created: / 12-06-2017 / 18:32:29 / cg"
+!
+
+ln2
+ "return the constant e as quad precision double.
+ (returns approx. 212 bits of precision)"
+
+ Ln2 isNil ifTrue:[
+ Ln2 := self fromDoubleArray(DoubleArray
+ with: 6.931471805599452862e-01
+ with: 2.319046813846299558e-17
+ with: 5.707708438416212066e-34
+ with: -3.582432210601811423e-50)
+ ].
+ ^ Ln2
+
+ "
+ self ln2
+ "
+
+ "Created: / 12-06-2017 / 18:31:34 / cg"
+!
+
+pi
+ "return the constant pi as quad precision double.
+ (returns approx. 212 bits of precision)"
+
+ Pi isNil ifTrue:[
+ Pi := self fromDoubleArray(DoubleArray
+ with: 3.141592653589793116e+00
+ with: 1.224646799147353207e-16
+ with: -2.994769809718339666e-33
+ with: 1.112454220863365282e-49)
+ ].
+ ^ Pi
+
+ "
+ self pi
+ "
+
+ "Created: / 12-06-2017 / 18:27:13 / cg"
+! !
+
+!QDouble class methodsFor:'queries'!
+
+epsilon
+ "return the maximum relative spacing of instances of mySelf
+ (i.e. the value-delta of the least significant bit)"
+
+ ^ Float epsilon
+
+ "
+ Float epsilon
+ ShortFloat epsilon
+ QDouble epsilon
+ "
+
+ "Created: / 12-06-2017 / 18:52:44 / cg"
+!
+
+numBitsInExponent
+ "answer the number of bits in the exponent"
+
+ ^ Float numBitsInExponent
+
+ "
+ 1.0 asQDouble class numBitsInExponent
+ "
+
+ "Created: / 12-06-2017 / 11:11:04 / cg"
+!
+
+numBitsInMantissa
+ "answer the number of bits in the mantissa"
+
+ ^ Float precision * 4
+
+ "
+ 1.0 class numBitsInMantissa
+ 1.0 asShortFloat class numBitsInMantissa
+ 1.0 asLongFloat class numBitsInMantissa
+ 1.0 asDDouble class numBitsInMantissa
+ 1.0 asQDouble class numBitsInMantissa
+
+ Float numBitsInMantissa
+ ShortFloat numBitsInMantissa
+ QDouble numBitsInMantissa
+ "
+
+ "Created: / 12-06-2017 / 11:13:44 / cg"
+ "Modified: / 12-06-2017 / 18:48:48 / cg"
+!
+
+precision
+ "answer the number of bits in the mantissa"
+
+ ^ Float precision * 4
+
+ "
+ 1.0 class numBitsInMantissa
+ 1.0 asShortFloat class numBitsInMantissa
+ 1.0 asLongFloat class numBitsInMantissa
+ 1.0 asDDouble class numBitsInMantissa
+ 1.0 asQDouble class numBitsInMantissa
+
+ Float numBitsInMantissa
+ ShortFloat numBitsInMantissa
+ QDouble numBitsInMantissa
+ QDouble precision
+ "
+
+ "Created: / 12-06-2017 / 18:49:11 / cg"
+!
+
+radix
+ "answer the radix of a Floats exponent
+ This is an IEEE float, which is represented as binary"
+
+ ^ Float radix
+
+ "Created: / 12-06-2017 / 18:50:04 / cg"
+! !
+
+!QDouble methodsFor:'arithmetic'!
+
+* aNumber
+ "return the product of the receiver and the argument, aNumber"
+
+ ^ aNumber productFromQDouble:self
+
+ "
+ ((QDouble fromFloat:1e20) + (QDouble fromFloat:1.0)) asDoubleArray
+ "
+
+ "Created: / 13-06-2017 / 01:00:47 / cg"
+!
+
++ aNumber
+ "return the sum of the receiver and the argument, aNumber"
+
+ ^ aNumber sumFromQDouble:self
+
+ "
+ ((QDouble fromFloat:1e20) + (QDouble fromFloat:1.0)) asDoubleArray
+ "
+
+ "Created: / 12-06-2017 / 16:17:46 / cg"
+ "Modified: / 12-06-2017 / 23:06:22 / cg"
+!
+
+- aNumber
+ "return the sum of the receiver and the argument, aNumber"
+
+ ^ (aNumber negated) sumFromQDouble:self
+
+ "
+ (QDouble fromFloat:1e20) asDoubleArray
+ ((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
+ "
+
+ "Created: / 12-06-2017 / 23:41:39 / cg"
+!
+
+negated
+ ^ self class
+ d0:(self d0) negated
+ d1:(self d1) negated
+ d2:(self d2) negated
+ d3:(self d3) negated
+
+ "
+ (QDouble fromFloat:1.0) negated
+ ((QDouble fromFloat:1e20) + (QDouble fromFloat:1.0)) negated asDoubleArray
+
+ (((QDouble fromFloat:1e20) + (QDouble fromFloat:1.0))
+ + ((QDouble fromFloat:1e20) + (QDouble fromFloat:1.0))) asDoubleArray
+ "
+
+ "Created: / 12-06-2017 / 20:14:55 / cg"
+ "Modified (comment): / 12-06-2017 / 23:46:57 / cg"
+! !
+
+!QDouble methodsFor:'coercing & converting'!
+
+asDoubleArray
+ |a|
+
+ a := DoubleArray new:4.
+%{
+ __DoubleArrayInstPtr(a)->d_element[0] = __QuadDoubleInstPtr(self)->d_quadDoubleValue[0];
+ __DoubleArrayInstPtr(a)->d_element[1] = __QuadDoubleInstPtr(self)->d_quadDoubleValue[1];
+ __DoubleArrayInstPtr(a)->d_element[2] = __QuadDoubleInstPtr(self)->d_quadDoubleValue[2];
+ __DoubleArrayInstPtr(a)->d_element[3] = __QuadDoubleInstPtr(self)->d_quadDoubleValue[3];
+%}.
+ ^ a
+
+ "
+ (QuadDouble fromFloat:1.0) asDoubleArray
+ (QuadDouble fromFloat:2.0) asDoubleArray
+ "
+
+ "Created: / 12-06-2017 / 18:19:19 / cg"
+!
+
+asFloat
+%{
+ RETURN ( __MKFLOAT(__QuadDoubleInstPtr(self)->d_quadDoubleValue[0]) );
+%}
+
+ "
+ (QDouble fromFloat:1.0) asFloat
+ (QDouble fromFloat:2.0) asFloat
+ "
+
+ "Created: / 12-06-2017 / 18:15:27 / cg"
+!
+
+coerce:aNumber
+ "convert the argument aNumber into an instance of the receiver's class and return it."
+
+ ^ aNumber asQDouble
+
+ "Created: / 12-06-2017 / 17:13:47 / cg"
+ "Modified: / 12-06-2017 / 21:09:06 / cg"
+!
+
+generality
+ "return the generality value - see ArithmeticValue>>retry:coercing:"
+
+ ^ 95
+
+ "Created: / 12-06-2017 / 17:13:14 / cg"
+!
+
+negative
+%{
+ RETURN ( __QuadDoubleInstPtr(self)->d_quadDoubleValue[0] < 0 ? true : false );
+%}
+
+ "
+ (QDouble fromFloat:0.0) negative
+ (QDouble fromFloat:1.0) negative
+ (QDouble fromFloat:-1.0) negative
+ "
+
+ "Created: / 13-06-2017 / 01:57:39 / cg"
+!
+
+positive
+%{
+ RETURN ( __QuadDoubleInstPtr(self)->d_quadDoubleValue[0] >= 0 ? true : false );
+%}
+
+ "
+ (QDouble fromFloat:1.0) positive
+ (QDouble fromFloat:-1.0) positive
+ "
+
+ "Created: / 13-06-2017 / 01:56:53 / cg"
+! !
+
+!QDouble methodsFor:'double dispatching'!
+
+differenceFromFloat:aFloat
+ "aFloat - self"
+
+ ^ aFloat + (self negated)
+
+ "
+ 1.0 - (QDouble fromFloat:1.0)
+ 1e20 - (QDouble fromFloat:1.0)
+ (1.0 - (QDouble fromFloat:1.0)) asFloat
+ (1e20 - (QDouble fromFloat:1.0)) asFloat
+
+ (1.0 - (QDouble fromFloat:1.0)) asDoubleArray
+ (1e20 - (QDouble fromFloat:1.0)) asDoubleArray
+ (1e20 - (QDouble fromFloat:1.0) + 1e-20) asDoubleArray
+ "
+
+ "Created: / 12-06-2017 / 23:38:05 / cg"
+!
+
+differenceFromQDouble:aQDouble
+ "aQDouble - self"
+
+ ^ aQDouble + (self negated)
+
+ "
+ 1.0 - (QDouble fromFloat:1.0)
+ 1e20 - (QDouble fromFloat:1.0)
+ (1.0 - (QDouble fromFloat:1.0)) asFloat
+ (1e20 - (QDouble fromFloat:1.0)) asFloat
+
+ (1.0 - (QDouble fromFloat:1.0)) asDoubleArray
+ (1e20 - (QDouble fromFloat:1.0)) asDoubleArray
+ (1e20 - (QDouble fromFloat:1.0) + 1e-20) asDoubleArray
+ "
+
+ "Created: / 12-06-2017 / 23:38:19 / cg"
+!
+
+equalFromQDouble:aQDouble
+%{
+ if (__Class(aQDouble) == QDouble) {
+ double *a = __QuadDoubleInstPtr(self)->d_quadDoubleValue;
+ double *b = __QuadDoubleInstPtr(aQDouble)->d_quadDoubleValue;
+
+ RETURN ((a[0] == b[0]
+ && a[1] == b[1]
+ && a[2] == b[2]
+ && a[3] == b[3]) ? true : false);
+ }
+%}.
+ ^ super equalFromQDouble:aQDouble
+
+ "
+ (QDouble fromFloat:1.0) = (QDouble fromFloat:1.0)
+ (QDouble fromFloat:1.0) = 1.0
+ 1.0 = (QDouble fromFloat:1.0)
+ "
+
+ "Created: / 13-06-2017 / 03:01:19 / cg"
+ "Modified (comment): / 13-06-2017 / 08:43:45 / cg"
+!
+
+floor
+%{
+ double *a = __QuadDoubleInstPtr(self)->d_quadDoubleValue;
+ OBJ newQD;
+
+ double x0, x1, x2, x3;
+ x1 = x2 = x3 = 0.0;
+ x0 =floor(a[0]);
+
+ if (x0 == a[0]) {
+ x1 = floor(a[1]);
+
+ if (x1 == a[1]) {
+ x2 = floor(a[2]);
+
+ if (x2 == a[2]) {
+ x3 = floor(a[3]);
+ }
+ }
+
+ m_renorm4(x0, x1, x2, x3);
+ __qNew_qdReal(newQD, x0, x1, x2, x3);
+ RETURN( newQD );
+ }
+
+ __qNew_qdReal(newQD, x0, x1, x2, x3);
+ RETURN( newQD );
+%}.
+
+ "
+ (QDouble fromFloat:4.0) floor
+ (QDouble fromFloat:4.1) floor
+ (QDouble fromFloat:0.1) floor
+ (0.1 + (QDouble fromFloat:1.0)) floor
+ (1e20 + (QDouble fromFloat:1.0)) floor
+ "
+
+ "Created: / 13-06-2017 / 01:52:44 / cg"
+!
+
+productFromFloat:aFloat
+%{
+ if (__isFloatLike(aFloat)) {
+ double *a = __QuadDoubleInstPtr(self)->d_quadDoubleValue;
+ double b = __floatVal(aFloat);
+ double p0, p1, p2, p3;
+ double q0, q1, q2;
+ double s0, s1, s2, s3, s4;
+ OBJ newQD;
+
+ m_two_prod(p0, a[0], b, q0);
+ m_two_prod(p1, a[1], b, q1);
+ m_two_prod(p2, a[2], b, q2);
+ p3 = a[3] * b;
+
+ s0 = p0;
+
+ m_two_sum(s1, q0, p1, s2);
+
+ m_three_sum(s2, q1, p2);
+
+ m_three_sum2(q1, q2, p3);
+ s3 = q1;
+
+ s4 = q2 + p2;
+
+ m_renorm5(s0, s1, s2, s3, s4);
+ __qNew_qdReal(newQD, s0, s1, s2, s3);
+ RETURN( newQD );
+ }
+%}.
+ ^ super productFromFloat:aFloat.
+
+ "
+ 2.0 * (QDouble fromFloat:1.0)
+ 1e20 * (QDouble fromFloat:1.0)
+ (2.0 * (QDouble fromFloat:1.0)) asFloat
+ (1e20 * (QDouble fromFloat:1.0)) asFloat
+
+ (1e20 * (QDouble fromFloat:1.0) * 1e-20) asDoubleArray
+ "
+
+ "Created: / 13-06-2017 / 00:58:56 / cg"
+!
+
+productFromQDouble:aQDouble
+%{
+ if (__Class(aQDouble) == QDouble) {
+ double *a = __QuadDoubleInstPtr(self)->d_quadDoubleValue;
+ double *b = __QuadDoubleInstPtr(aQDouble)->d_quadDoubleValue;
+ OBJ newQD;
+// sloppy
+ double p0, p1, p2, p3, p4, p5;
+ double q0, q1, q2, q3, q4, q5;
+ double t0, t1;
+ double s0, s1, s2;
+
+ m_two_prod(p0, a[0], b[0], q0);
+
+ m_two_prod(p1, a[0], b[1], q1);
+ m_two_prod(p2, a[1], b[0], q2);
+
+ m_two_prod(p3, a[0], b[2], q3);
+ m_two_prod(p4, a[1], b[1], q4);
+ m_two_prod(p5, a[2], b[0], q5);
+
+ /* Start Accumulation */
+ m_three_sum(p1, p2, q0);
+
+ /* Six-Three Sum of p2, q1, q2, p3, p4, p5. */
+ m_three_sum(p2, q1, q2);
+ m_three_sum(p3, p4, p5);
+ /* compute (s0, s1, s2) = (p2, q1, q2) + (p3, p4, p5). */
+ m_two_sum(s0, p2, p3, t0);
+ m_two_sum(s1, q1, p4, t1);
+ s2 = q2 + p5;
+ m_two_sum(s1, s1, t0, t0);
+ s2 += (t0 + t1);
+
+ /* O(eps^3) order terms */
+ s1 += a[0]*b[3] + a[1]*b[2] + a[2]*b[1] + a[3]*b[0] + q0 + q3 + q4 + q5;
+ m_renorm5(p0, p1, s0, s1, s2);
+
+ __qNew_qdReal(newQD, p0, p1, s0, s1);
+ RETURN( newQD );
+ }
+%}.
+ ^ super productFromQDouble:aQDouble.
+
+ "
+ 2.0 * (QDouble fromFloat:1.0)
+ 1e20 * (QDouble fromFloat:1.0)
+ (2.0 * (QDouble fromFloat:1.0)) asFloat
+ (1e20 * (QDouble fromFloat:1.0)) asFloat
+
+ (1e20 * (QDouble fromFloat:1.0) * 1e-20) asDoubleArray
+ "
+
+ "Created: / 13-06-2017 / 01:06:22 / cg"
+!
+
+squared
+%{
+ double *a = __QuadDoubleInstPtr(self)->d_quadDoubleValue;
+ double p0, p1, p2, p3, p4, p5;
+ double q0, q1, q2, q3;
+ double s0, s1;
+ double t0, t1;
+ double t;
+ OBJ newQD;
+
+ m_two_sqr(p0, a[0], q0);
+ t = 2.0 * a[0];
+
+ m_two_prod(p1, t, a[1], q1);
+ m_two_prod(p2, t, a[2], q2);
+ m_two_sqr(p3, a[1], q3);
+
+ m_two_sum(p1, q0, p1, q0);
+
+ m_two_sum(q0, q0, q1, q1);
+ m_two_sum(p2, p2, p3, p3);
+
+ m_two_sum(s0, q0, p2, t0);
+ m_two_sum(s1, q1, p3, t1);
+
+ m_two_sum(s1, s1, t0, t0);
+ t0 += t1;
+
+ m_quick_two_sum(s1, s1, t0, t0);
+ m_quick_two_sum(p2, s0, s1, t1);
+ m_quick_two_sum(p3, t1, t0, q0);
+
+ p4 = 2.0 * a[0] * a[3];
+ p5 = 2.0 * a[1] * a[2];
+
+ m_two_sum(p4, p4, p5, p5);
+ m_two_sum(q2, q2, q3, q3);
+
+ m_two_sum(t0, p4, q2, t1);
+ t1 = t1 + p5 + q3;
+
+ m_two_sum(p3, p3, t0, p4);
+ p4 = p4 + q0 + t1;
+
+ m_renorm5(p0, p1, p2, p3, p4);
+
+ __qNew_qdReal(newQD, p0, p1, s0, s1);
+ RETURN( newQD );
+%}.
+
+ "
+ (QDouble fromFloat:4.0) squared
+ (1e20 + (QDouble fromFloat:1.0)) squared
+ "
+
+ "Created: / 13-06-2017 / 01:27:58 / cg"
+!
+
+sumFromFloat:aFloat
+%{
+ if (__isFloatLike(aFloat)) {
+ double *a = __QuadDoubleInstPtr(self)->d_quadDoubleValue;
+ double b = __floatVal(aFloat);
+ double c0, c1, c2, c3;
+ double e;
+ OBJ newQD;
+
+ m_two_sum(c0, a[0], b, e);
+ m_two_sum(c1 ,a[1], e, e);
+ m_two_sum(c2, a[2], e, e);
+ m_two_sum(c3, a[3], e, e);
+
+ m_renorm5(c0, c1, c2, c3, e);
+ __qNew_qdReal(newQD, c0, c1, c2, c3);
+ RETURN( newQD );
+ }
+%}.
+ ^ super sumFromFloat:aFloat.
+
+ "
+ 1.0 + (QDouble fromFloat:1.0)
+ 1e20 + (QDouble fromFloat:1.0)
+ (1.0 + (QDouble fromFloat:1.0)) asFloat
+ (1e20 + (QDouble fromFloat:1.0)) asFloat
+
+ (1.0 + (QDouble fromFloat:1.0)) asDoubleArray
+ (1e20 + (QDouble fromFloat:1.0)) asDoubleArray
+ (1e20 + (QDouble fromFloat:1.0) + 1e-20) asDoubleArray
+ "
+
+ "Created: / 12-06-2017 / 17:16:41 / cg"
+ "Modified: / 12-06-2017 / 22:57:03 / cg"
+!
+
+sumFromQDouble:aQDouble
+%{
+ if (__Class(aQDouble) == QDouble) {
+ double *a = __QuadDoubleInstPtr(self)->d_quadDoubleValue;
+ double *b = __QuadDoubleInstPtr(aQDouble)->d_quadDoubleValue;
+ OBJ newQD;
+
+#ifndef QD_IEEE_ADD
+ // sloppy_add...
+
+ /*
+ double s0, s1, s2, s3;
+ double t0, t1, t2, t3;
+
+ m_two_sum(s0, a[0], b[0], t0);
+ m_two_sum(s1, a[1], b[1], t1);
+ m_two_sum(s2, a[2], b[2], t2);
+ m_two_sum(s3, a[3], b[3], t3);
+
+ m_two_sum(s1, s1, t0, t0);
+ m_three_sum(s2, t0, t1);
+ m_three_sum2(s3, t0, t2);
+ t0 = t0 + t1 + t3;
+
+ m_renorm5(s0, s1, s2, s3, t0);
+ return qd_real(s0, s1, s2, s3, t0);
+ */
+
+ /* Same as above, but addition re-organized to minimize
+ data dependency ... unfortunately some compilers are
+ not very smart to do this automatically */
+ double s0, s1, s2, s3;
+ double t0, t1, t2, t3;
+
+ double v0, v1, v2, v3;
+ double u0, u1, u2, u3;
+ double w0, w1, w2, w3;
+
+ s0 = a[0] + b[0];
+ s1 = a[1] + b[1];
+ s2 = a[2] + b[2];
+ s3 = a[3] + b[3];
+
+ v0 = s0 - a[0];
+ v1 = s1 - a[1];
+ v2 = s2 - a[2];
+ v3 = s3 - a[3];
+
+ u0 = s0 - v0;
+ u1 = s1 - v1;
+ u2 = s2 - v2;
+ u3 = s3 - v3;
+
+ w0 = a[0] - u0;
+ w1 = a[1] - u1;
+ w2 = a[2] - u2;
+ w3 = a[3] - u3;
+
+ u0 = b[0] - v0;
+ u1 = b[1] - v1;
+ u2 = b[2] - v2;
+ u3 = b[3] - v3;
+
+ t0 = w0 + u0;
+ t1 = w1 + u1;
+ t2 = w2 + u2;
+ t3 = w3 + u3;
+
+ m_two_sum(s1, s1, t0, t0);
+ m_three_sum(s2, t0, t1);
+ m_three_sum2(s3, t0, t2);
+ t0 = t0 + t1 + t3;
+
+ /* renormalize */
+ m_renorm5(s0, s1, s2, s3, t0);
+ __qNew_qdReal(newQD, s0, s1, s2, s3);
+ RETURN(newQD);
+#else
+ // ieee_add...
+ int i, j, k;
+ double s, t;
+ double u, v; /* double-length accumulator */
+ double x[4] = {0.0, 0.0, 0.0, 0.0};
+
+ i = j = k = 0;
+ if (abs(a[i]) > abs(b[j]))
+ u = a[i++];
+ else
+ u = b[j++];
+ if (abs(a[i]) > abs(b[j]))
+ v = a[i++];
+ else
+ v = b[j++];
+
+ u = quick_two_sum(u, v, v);
+
+ while (k < 4) {
+ if (i >= 4 && j >= 4) {
+ x[k] = u;
+ if (k < 3)
+ x[++k] = v;
+ break;
+ }
+
+ if (i >= 4)
+ t = b[j++];
+ else if (j >= 4)
+ t = a[i++];
+ else if (abs(a[i]) > abs(b[j])) {
+ t = a[i++];
+ } else
+ t = b[j++];
+
+ s = quick_three_accum(u, v, t);
+
+ if (s != 0.0) {
+ x[k++] = s;
+ }
+ }
+
+ /* add the rest. */
+ for (k = i; k < 4; k++)
+ x[3] += a[k];
+ for (k = j; k < 4; k++)
+ x[3] += b[k];
+
+ m_renorm4(x[0], x[1], x[2], x[3]);
+ __qNew_qdReal(newQD, x[0], x[1], x[2], x[3]);
+ RETURN(newQD);
+#endif
+ }
+%}.
+ ^ super sumFromQDouble:aQDouble
+
+ "
+ (QDouble fromFloat:1.0) + (QDouble fromFloat:1.0)
+ (QDouble fromFloat:1.0) + 1.0
+ 1.0 + (QDouble fromFloat:1.0)
+
+ ((QDouble fromFloat:1.0) + (QDouble fromFloat:1.0)) asDoubleArray
+ ((QDouble fromFloat:1.0) + 1.0) asDoubleArray
+ (1.0 + (QDouble fromFloat:1.0)) asDoubleArray
+ (1e-20 + (QDouble fromFloat:1.0)) asDoubleArray
+ (1e20 + (QDouble fromFloat:1.0)) asDoubleArray
+ "
+
+ "Created: / 12-06-2017 / 21:15:43 / cg"
+ "Modified: / 13-06-2017 / 00:30:45 / cg"
+! !
+
+!QDouble methodsFor:'inspecting'!
+
+inspectorExtraAttributes
+ "extra (pseudo instvar) entries to be shown in an inspector."
+
+ ^ super inspectorExtraAttributes
+ add:'-{doubles}' ->
+ [
+ self asDoubleArray printString
+ ];
+ yourself
+
+ "Created: / 12-06-2017 / 23:43:05 / cg"
+! !
+
+!QDouble methodsFor:'printing & storing'!
+
+printString
+ "return a printed representation of the receiver"
+
+ self d1 = 0.0 ifTrue:[
+ ^ self d0 printString
+ ].
+ ^ self d0 printString , '...'
+
+ "Created: / 12-06-2017 / 23:41:04 / cg"
+! !
+
+!QDouble methodsFor:'private accessing'!
+
+d0
+%{
+ RETURN ( __MKFLOAT(__QuadDoubleInstPtr(self)->d_quadDoubleValue[0]) );
+%}
+
+ "Created: / 12-06-2017 / 20:15:12 / cg"
+!
+
+d1
+%{
+ RETURN ( __MKFLOAT(__QuadDoubleInstPtr(self)->d_quadDoubleValue[1]) );
+%}
+
+ "Created: / 12-06-2017 / 20:15:12 / cg"
+!
+
+d2
+%{
+ RETURN ( __MKFLOAT(__QuadDoubleInstPtr(self)->d_quadDoubleValue[2]) );
+%}
+
+ "Created: / 12-06-2017 / 20:15:29 / cg"
+!
+
+d3
+%{
+ RETURN ( __MKFLOAT(__QuadDoubleInstPtr(self)->d_quadDoubleValue[3]) );
+%}
+
+ "Created: / 12-06-2017 / 20:15:32 / cg"
+! !
+
+!QDouble class methodsFor:'documentation'!
+
+version
+ ^ '$Header$'
+!
+
+version_CVS
+ ^ '$Header$'
+! !
+