cfad47cfa3/t3compiler/tads3/include/bignum.h

4b825dc642cb6eb9a060e54bf8d69288fbee4904cfad47cfa334b206c65f22086bcc5d63e6f70944
1
#charset "us-ascii"
2
3
/* 
4
 *   Copyright (c) 2000, 2006 Michael J. Roberts
5
 *   
6
 *   This file is part of TADS 3.
7
 *   
8
 *   This header defines the BigNumber intrinsic class.  
9
 */
10
11
#ifndef _BIGNUM_H_
12
#define _BIGNUM_H_
13
14
/* include our base class definition */
15
#include "systype.h"
16
17
/*
18
 *   The BigNumber intrinsic class lets you perform floating-point and
19
 *   integer arithmetic with (almost) any desired precision.  BigNumber uses
20
 *   a decimal representation, which means that decimal values can be
21
 *   represented exactly (i.e., with no rounding errors, as can happen with
22
 *   IEEE 'double' and 'float' values that languages like C typically
23
 *   support).  BigNumber combines a varying-length mantissa with an
24
 *   exponent; the length of the mantissa determines how many digits of
25
 *   precision a given BigNumber can store, and the exponent lets you
26
 *   represent very large or very small values with minimal storage.  You can
27
 *   specify the desired precision when you create a BigNumber explicitly;
28
 *   when BigNumber values are created implicitly by computations, the system
29
 *   chooses a precision based on the inputs to the calculations, typically
30
 *   equal to the largest of the precisions of the input values.
31
 *   
32
 *   The maximum precision for a BigNumber is about 64,000 digits, and the
33
 *   exponent can range from -32768 to +32767.  Since this is a decimal
34
 *   exponent, this implies an absolute value range from 1.0e-32768 to
35
 *   1.0e+32767.  The more digits of precision stored in a given BigNumber
36
 *   value, the more memory the object consumes, and the more time it takes
37
 *   to perform calculations using the value.  
38
 */
39
intrinsic class BigNumber 'bignumber/030000': Object
40
{
41
    /* format to a string */
42
    formatString(maxDigits, flags?,
43
                 wholePlaces?, fracDigits?, expDigits?, leadFiller?);
44
45
    /* 
46
     *   compare for equality after rounding to the smaller of my
47
     *   precision and num's precision 
48
     */
49
    equalRound(num);
50
51
    /* 
52
     *   returns an integer giving the number of digits of precision that
53
     *   this number stores 
54
     */
55
    getPrecision();
56
57
    /* 
58
     *   Return a new number, with the same value as this number but with
59
     *   the given number of decimal digits of precision.  If the new
60
     *   precision is higher than the old precision, this will increase
61
     *   the precision to the requested new size and add trailing zeroes
62
     *   to the value.  If the new precision is lower than the old
63
     *   precision, we'll round the number for the reduced precision.  
64
     */
65
    setPrecision(digits);
66
67
    /* get the fractional part */
68
    getFraction();
69
70
    /* get the whole part (truncates the fraction - doesn't round) */
71
    getWhole();
72
73
    /* 
74
     *   round to the given number of digits after the decimal point; if
75
     *   the value is zero, round to integer; if the value is negative,
76
     *   round to the given number of places before the decimal point 
77
     */
78
    roundToDecimal(places);
79
80
    /* return the absolute value */
81
    getAbs();
82
83
    /* least integer greater than or equal to this number */
84
    getCeil();
85
86
    /* greatest integer less than or equal to this number */
87
    getFloor();
88
89
    /* get the base-10 scale of the number */
90
    getScale();
91
92
    /* 
93
     *   scale by 10^x - if x is positive, this multiplies the number by
94
     *   ten the given number of times; if x is negative, this divides the
95
     *   number by ten the given number of times 
96
     */
97
    scaleTen(x);
98
99
    /* negate - invert the sign of the number */
100
    negate();
101
102
    /* 
103
     *   copySignFrom - combine the absolute value of self with the sign
104
     *   of x 
105
     */
106
    copySignFrom(x);
107
108
    /* determine if the value is negative */
109
    isNegative();
110
111
    /* 
112
     *   Calculate the integer quotient and the remainder; returns a list
113
     *   whose first element is the integer quotient (a BigNumber
114
     *   containing an integer value), and whose second element is the
115
     *   remainder (the value R such that dividend = quotient*x + R).
116
     *   
117
     *   Note that the quotient returned will not necessarily have the
118
     *   same value as the whole part of dividing self by x with the '/'
119
     *   operator, because this division handles rounding differently.  In
120
     *   particular, the '/' operator will perform the appropriate
121
     *   rounding on the quotient if the quotient has insufficient
122
     *   precision to represent the exact result.  This routine, in
123
     *   contrast, does NOT round the quotient, but merely truncates any
124
     *   trailing digits that cannot be represented in the result's
125
     *   precision.  The reason for this difference is that it ensures
126
     *   that the relation (dividend=quotient*x+remainder) holds, which
127
     *   would not always be the case if the quotient were rounded up.
128
     *   
129
     *   Note also that the remainder will not necessarily be less than
130
     *   the divisor.  If the quotient cannot be exactly represented
131
     *   (which occurs if the precision of the quotient is smaller than
132
     *   its scale), the remainder will be the correct value so that the
133
     *   relationship above holds, rather than the unique remainder that
134
     *   is smaller than the divisor.  In all cases where there is
135
     *   sufficient precision to represent the quotient exactly (to the
136
     *   units digit only, since the quotient returned from this method
137
     *   will always be an integer), the remainder will satisfy the
138
     *   relationship AND will be the unique remainder with absolute value
139
     *   less than the divisor.  
140
     */
141
    divideBy(x);
142
143
    /* 
144
     *   calculate and return the trigonometric sine of the value (taken
145
     *   as a radian value) 
146
     */
147
    sine();
148
149
    /* 
150
     *   calculate and return the trigonometric cosine of the value (taken
151
     *   as a radian value) 
152
     */
153
    cosine();
154
155
    /* 
156
     *   calculate and return the trigonometric tangent of the value
157
     *   (taken as a radian value) 
158
     */
159
    tangent();
160
161
    /* 
162
     *   interpreting this number as a number of degrees, convert the
163
     *   value to radians and return the result 
164
     */
165
    degreesToRadians();
166
167
    /* 
168
     *   interpreting this number as a number of radians, convert the
169
     *   value to degrees and return the result 
170
     */
171
    radiansToDegrees();
172
173
    /* 
174
     *   Calculate and return the arcsine (in radians) of the value.  Note
175
     *   that the value must be between -1 and +1 inclusive, since sine()
176
     *   never has a value outside of this range. 
177
     */
178
    arcsine();
179
180
    /* 
181
     *   Calculate and return the arccosine (in radians).  The value must
182
     *   be between -1 and +1 inclusive. 
183
     */
184
    arccosine();
185
186
    /* calculate and return the arctangent (in radians) */
187
    arctangent();
188
189
    /* calculate the square root and return the result */
190
    sqrt();
191
192
    /* 
193
     *   calculate the natural logarithm of this number and return the
194
     *   result 
195
     */
196
    logE();
197
198
    /* 
199
     *   raise e (the base of the natural logarithm) to the power of this
200
     *   value and return the result 
201
     */
202
    expE();
203
204
    /* calculate the base-10 logarithm of the number and return the result */
205
    log10();
206
207
    /* 
208
     *   raise this number to the power of the argument and return the
209
     *   result 
210
     */
211
    raiseToPower(x);
212
213
    /* calculate the hyperbolic sine, cosine, and tangent */
214
    sinh();
215
    cosh();
216
    tanh();
217
218
    /* get the value of pi to a given precision */
219
    getPi(digits);
220
221
    /* get the value of e to a given precision */
222
    getE(digits);
223
}
224
225
/*
226
 *   flags for formatString 
227
 */
228
229
/* always show a sign, even if positive */
230
#define BignumSign          0x0001
231
232
/* always show in exponential format */
233
#define BignumExp           0x0002
234
235
/* always show a sign in the exponent, even if positive */
236
#define BignumExpSign      0x0004
237
238
/* 
239
 *   show a zero before the decimal point - this is only relevant in
240
 *   non-exponential format when the number is between -1 and +1 
241
 */
242
#define BignumLeadingZero  0x0008
243
244
/* always show a decimal point */
245
#define BignumPoint         0x0010
246
247
/* insert commas to denote thousands, millions, etc */
248
#define BignumCommas        0x0020
249
250
/* show a leading space if the number is positive */
251
#define BignumPosSpace     0x0040
252
253
/* 
254
 *   use European-style formatting: use a comma instead of a period for
255
 *   the decimal point, and use periods instead of commas to set off
256
 *   thousands, millions, etc 
257
 */
258
#define BignumEuroStyle     0x0080
259
260
#endif /* _BIGNUM_H_ */
261