]> www.ginac.de Git - cln.git/blob - include/cln/rational.h
Replace CL_REQUIRE/CL_PROVIDE(cl_I_ring) with portable code.
[cln.git] / include / cln / rational.h
1 // Public rational number operations.
2
3 #ifndef _CL_RATIONAL_H
4 #define _CL_RATIONAL_H
5
6 #include "cln/number.h"
7 #include "cln/rational_class.h"
8 #include "cln/integer_class.h"
9 #include "cln/exception.h"
10
11 namespace cln {
12
13 CL_DEFINE_AS_CONVERSION(cl_RA)
14
15
16 // numerator(r) liefert den Zähler der rationalen Zahl r.
17 extern const cl_I numerator (const cl_RA& r);
18
19 // denominator(r) liefert den Nenner (> 0) der rationalen Zahl r.
20 extern const cl_I denominator (const cl_RA& r);
21
22
23 // Liefert (- r), wo r eine rationale Zahl ist.
24 extern const cl_RA operator- (const cl_RA& r);
25
26 // (+ r s), wo r und s rationale Zahlen sind.
27 extern const cl_RA operator+ (const cl_RA& r, const cl_RA& s);
28 // Dem C++-Compiler muß man auch das Folgende sagen:
29 inline const cl_RA operator+ (const int x, const cl_RA& y)
30         { return cl_I(x) + y; }
31 inline const cl_RA operator+ (const unsigned int x, const cl_RA& y)
32         { return cl_I(x) + y; }
33 inline const cl_RA operator+ (const long x, const cl_RA& y)
34         { return cl_I(x) + y; }
35 inline const cl_RA operator+ (const unsigned long x, const cl_RA& y)
36         { return cl_I(x) + y; }
37 #ifdef HAVE_LONGLONG
38 inline const cl_RA operator+ (const long long x, const cl_RA& y)
39         { return cl_I(x) + y; }
40 inline const cl_RA operator+ (const unsigned long long x, const cl_RA& y)
41         { return cl_I(x) + y; }
42 #endif
43 inline const cl_RA operator+ (const cl_RA& x, const int y)
44         { return x + cl_I(y); }
45 inline const cl_RA operator+ (const cl_RA& x, const unsigned int y)
46         { return x + cl_I(y); }
47 inline const cl_RA operator+ (const cl_RA& x, const long y)
48         { return x + cl_I(y); }
49 inline const cl_RA operator+ (const cl_RA& x, const unsigned long y)
50         { return x + cl_I(y); }
51 #ifdef HAVE_LONGLONG
52 inline const cl_RA operator+ (const cl_RA& x, const long long y)
53         { return x + cl_I(y); }
54 inline const cl_RA operator+ (const cl_RA& x, const unsigned long long y)
55         { return x + cl_I(y); }
56 #endif
57
58 // (- r s), wo r und s rationale Zahlen sind.
59 extern const cl_RA operator- (const cl_RA& r, const cl_RA& s);
60 // Dem C++-Compiler muß man auch das Folgende sagen:
61 inline const cl_RA operator- (const int x, const cl_RA& y)
62         { return cl_I(x) - y; }
63 inline const cl_RA operator- (const unsigned int x, const cl_RA& y)
64         { return cl_I(x) - y; }
65 inline const cl_RA operator- (const long x, const cl_RA& y)
66         { return cl_I(x) - y; }
67 inline const cl_RA operator- (const unsigned long x, const cl_RA& y)
68         { return cl_I(x) - y; }
69 #ifdef HAVE_LONGLONG
70 inline const cl_RA operator- (const long long x, const cl_RA& y)
71         { return cl_I(x) - y; }
72 inline const cl_RA operator- (const unsigned long long x, const cl_RA& y)
73         { return cl_I(x) - y; }
74 #endif
75 inline const cl_RA operator- (const cl_RA& x, const int y)
76         { return x - cl_I(y); }
77 inline const cl_RA operator- (const cl_RA& x, const unsigned int y)
78         { return x - cl_I(y); }
79 inline const cl_RA operator- (const cl_RA& x, const long y)
80         { return x - cl_I(y); }
81 inline const cl_RA operator- (const cl_RA& x, const unsigned long y)
82         { return x - cl_I(y); }
83 #ifdef HAVE_LONGLONG
84 inline const cl_RA operator- (const cl_RA& x, const long long y)
85         { return x - cl_I(y); }
86 inline const cl_RA operator- (const cl_RA& x, const unsigned long long y)
87         { return x - cl_I(y); }
88 #endif
89
90 // (1+ r), wo r eine rationale Zahl ist.
91 extern const cl_RA plus1 (const cl_RA& r);
92
93 // (1- r), wo r eine rationale Zahl ist.
94 extern const cl_RA minus1 (const cl_RA& r);
95
96 // (abs r), wo r eine rationale Zahl ist.
97 extern const cl_RA abs (const cl_RA& r);
98
99 // equal(r,s) vergleicht zwei rationale Zahlen r und s auf Gleichheit.
100 extern bool equal (const cl_RA& r, const cl_RA& s);
101 // equal_hashcode(r) liefert einen equal-invarianten Hashcode für r.
102 extern uint32 equal_hashcode (const cl_RA& r);
103
104 // compare(r,s) vergleicht zwei rationale Zahlen r und s.
105 // Ergebnis: 0 falls r=s, +1 falls r>s, -1 falls r<s.
106 extern cl_signean compare (const cl_RA& r, const cl_RA& s);
107
108 inline bool operator== (const cl_RA& x, const cl_RA& y)
109         { return equal(x,y); }
110 inline bool operator!= (const cl_RA& x, const cl_RA& y)
111         { return !equal(x,y); }
112 inline bool operator<= (const cl_RA& x, const cl_RA& y)
113         { return compare(x,y)<=0; }
114 inline bool operator< (const cl_RA& x, const cl_RA& y)
115         { return compare(x,y)<0; }
116 inline bool operator>= (const cl_RA& x, const cl_RA& y)
117         { return compare(x,y)>=0; }
118 inline bool operator> (const cl_RA& x, const cl_RA& y)
119         { return compare(x,y)>0; }
120
121 // minusp(x) == (< x 0)
122 extern bool minusp (const cl_RA& x);
123
124 // zerop(x) stellt fest, ob eine rationale Zahl = 0 ist.
125 extern bool zerop (const cl_RA& x);
126
127 // plusp(x) == (> x 0)
128 extern bool plusp (const cl_RA& x);
129
130 // Kehrwert (/ r), wo r eine rationale Zahl ist.
131 extern const cl_RA recip (const cl_RA& r);
132
133 // Liefert (* r s), wo r und s rationale Zahlen sind.
134 extern const cl_RA operator* (const cl_RA& r, const cl_RA& s);
135 // Dem C++-Compiler muß man auch das Folgende sagen:
136 inline const cl_RA operator* (const int x, const cl_RA& y)
137         { return cl_I(x) * y; }
138 inline const cl_RA operator* (const unsigned int x, const cl_RA& y)
139         { return cl_I(x) * y; }
140 inline const cl_RA operator* (const long x, const cl_RA& y)
141         { return cl_I(x) * y; }
142 inline const cl_RA operator* (const unsigned long x, const cl_RA& y)
143         { return cl_I(x) * y; }
144 #ifdef HAVE_LONGLONG
145 inline const cl_RA operator* (const long long x, const cl_RA& y)
146         { return cl_I(x) * y; }
147 inline const cl_RA operator* (const unsigned long long x, const cl_RA& y)
148         { return cl_I(x) * y; }
149 #endif
150 inline const cl_RA operator* (const cl_RA& x, const int y)
151         { return x * cl_I(y); }
152 inline const cl_RA operator* (const cl_RA& x, const unsigned int y)
153         { return x * cl_I(y); }
154 inline const cl_RA operator* (const cl_RA& x, const long y)
155         { return x * cl_I(y); }
156 inline const cl_RA operator* (const cl_RA& x, const unsigned long y)
157         { return x * cl_I(y); }
158 #ifdef HAVE_LONGLONG
159 inline const cl_RA operator* (const cl_RA& x, const long long y)
160         { return x * cl_I(y); }
161 inline const cl_RA operator* (const cl_RA& x, const unsigned long long y)
162         { return x * cl_I(y); }
163 #endif
164
165 // Quadrat (* r r), wo r eine rationale Zahl ist.
166 extern const cl_RA square (const cl_RA& r);
167
168 // Liefert (/ r s), wo r und s rationale Zahlen sind.
169 extern const cl_RA operator/ (const cl_RA& r, const cl_RA& s);
170 // Dem C++-Compiler muß man auch das Folgende sagen:
171 inline const cl_RA operator/ (const int x, const cl_RA& y)
172         { return cl_I(x) / y; }
173 inline const cl_RA operator/ (const unsigned int x, const cl_RA& y)
174         { return cl_I(x) / y; }
175 inline const cl_RA operator/ (const long x, const cl_RA& y)
176         { return cl_I(x) / y; }
177 inline const cl_RA operator/ (const unsigned long x, const cl_RA& y)
178         { return cl_I(x) / y; }
179 #ifdef HAVE_LONGLONG
180 inline const cl_RA operator/ (const long long x, const cl_RA& y)
181         { return cl_I(x) / y; }
182 inline const cl_RA operator/ (const unsigned long long x, const cl_RA& y)
183         { return cl_I(x) / y; }
184 #endif
185 inline const cl_RA operator/ (const cl_RA& x, const int y)
186         { return x / cl_I(y); }
187 inline const cl_RA operator/ (const cl_RA& x, const unsigned int y)
188         { return x / cl_I(y); }
189 inline const cl_RA operator/ (const cl_RA& x, const long y)
190         { return x / cl_I(y); }
191 inline const cl_RA operator/ (const cl_RA& x, const unsigned long y)
192         { return x / cl_I(y); }
193 #ifdef HAVE_LONGLONG
194 inline const cl_RA operator/ (const cl_RA& x, const long long y)
195         { return x / cl_I(y); }
196 inline const cl_RA operator/ (const cl_RA& x, const unsigned long long y)
197         { return x / cl_I(y); }
198 #endif
199
200 // Return type for rounding operators.
201 // x / y  --> (q,r) with x = y*q+r.
202 struct cl_RA_div_t {
203         cl_I quotient;
204         cl_RA remainder;
205 // Constructor.
206         cl_RA_div_t () {}
207         cl_RA_div_t (const cl_I& q, const cl_RA& r) : quotient(q), remainder(r) {}
208 };
209
210 // Liefert ganzzahligen und gebrochenen Anteil einer rationalen Zahl.
211 // (q,r) := (floor x)
212 // floor2(x)
213 // > x: rationale Zahl
214 // < q,r: Quotient q, ein Integer, Rest r, eine rationale Zahl
215   extern const cl_RA_div_t floor2 (const cl_RA& x);
216   extern const cl_I floor1 (const cl_RA& x);
217
218 // Liefert ganzzahligen und gebrochenen Anteil einer rationalen Zahl.
219 // (q,r) := (ceiling x)
220 // ceiling2(x)
221 // > x: rationale Zahl
222 // < q,r: Quotient q, ein Integer, Rest r, eine rationale Zahl
223   extern const cl_RA_div_t ceiling2 (const cl_RA& x);
224   extern const cl_I ceiling1 (const cl_RA& x);
225
226 // Liefert ganzzahligen und gebrochenen Anteil einer rationalen Zahl.
227 // (q,r) := (truncate x)
228 // truncate2(x)
229 // > x: rationale Zahl
230 // < q,r: Quotient q, ein Integer, Rest r, eine rationale Zahl
231   extern const cl_RA_div_t truncate2 (const cl_RA& x);
232   extern const cl_I truncate1 (const cl_RA& x);
233
234 // Liefert ganzzahligen und gebrochenen Anteil einer rationalen Zahl.
235 // (q,r) := (round x)
236 // round2(x)
237 // > x: rationale Zahl
238 // < q,r: Quotient q, ein Integer, Rest r, eine rationale Zahl
239   extern const cl_RA_div_t round2 (const cl_RA& x);
240   extern const cl_I round1 (const cl_RA& x);
241
242 // floor2(x,y) liefert (floor x y).
243 extern const cl_RA_div_t floor2 (const cl_RA& x, const cl_RA& y);
244 extern const cl_I floor1 (const cl_RA& x, const cl_RA& y);
245
246 // ceiling2(x,y) liefert (ceiling x y).
247 extern const cl_RA_div_t ceiling2 (const cl_RA& x, const cl_RA& y);
248 extern const cl_I ceiling1 (const cl_RA& x, const cl_RA& y);
249
250 // truncate2(x,y) liefert (truncate x y).
251 extern const cl_RA_div_t truncate2 (const cl_RA& x, const cl_RA& y);
252 extern const cl_I truncate1 (const cl_RA& x, const cl_RA& y);
253
254 // round2(x,y) liefert (round x y).
255 extern const cl_RA_div_t round2 (const cl_RA& x, const cl_RA& y);
256 extern const cl_I round1 (const cl_RA& x, const cl_RA& y);
257
258 // max(x,y) liefert (max x y), wo x und y rationale Zahlen sind.
259 extern const cl_RA max (const cl_RA& x, const cl_RA& y);
260
261 // min(x,y) liefert (min x y), wo x und y rationale Zahlen sind.
262 extern const cl_RA min (const cl_RA& x, const cl_RA& y);
263
264 // signum(x) liefert (signum x), wo x eine rationale Zahl ist.
265 extern const cl_RA signum (const cl_RA& x);
266
267 // (expt x y), wo x eine rationale Zahl und y ein Integer >0 ist.
268 extern const cl_RA expt_pos (const cl_RA& x, uintL y);
269 extern const cl_RA expt_pos (const cl_RA& x, const cl_I& y);
270
271 // (expt x y), wo x eine rationale Zahl und y ein Integer ist.
272 extern const cl_RA expt (const cl_RA& x, sintL y);
273 extern const cl_RA expt (const cl_RA& x, const cl_I& y);
274
275 // Stellt fest, ob eine rationale Zahl >=0 das Quadrat einer rationalen Zahl
276 // ist.
277 // sqrtp(x,&w)
278 // > x: eine rationale Zahl >=0
279 // < w: rationale Zahl (sqrt x) falls x Quadratzahl
280 // < ergebnis: true      ..................., false sonst
281   extern bool sqrtp (const cl_RA& x, cl_RA* w);
282
283 // Stellt fest, ob eine rationale Zahl >=0 die n-te Potenz einer rationalen Zahl
284 // ist.
285 // rootp(x,n,&w)
286 // > x: eine rationale Zahl >=0
287 // > n: ein Integer >0
288 // < w: exakte n-te Wurzel (expt x (/ n)) falls x eine n-te Potenz
289 // < ergebnis: true                       ........................, false sonst
290   extern bool rootp (const cl_RA& x, uintL n, cl_RA* w);
291   extern bool rootp (const cl_RA& x, const cl_I& n, cl_RA* w);
292
293 // Liefert zu Integers a>0, b>1 den Logarithmus log(a,b),
294 // falls er eine rationale Zahl ist.
295 // logp(a,b,&l)
296 // > a: ein Integer >0
297 // > b: ein Integer >1
298 // < l: log(a,b)       falls er eine exakte rationale Zahl ist
299 // < ergebnis: true    ......................................., false sonst
300   extern bool logp (const cl_I& a, const cl_I& b, cl_RA* l);
301
302 // Liefert zu rationalen Zahlen a>0, b>0 den Logarithmus log(a,b),
303 // falls er eine rationale Zahl ist.
304 // logp(a,b,&l)
305 // > a: eine rationale Zahl >0
306 // > b: eine rationale Zahl >0, /=1
307 // < l: log(a,b)       falls er eine exakte rationale Zahl ist
308 // < ergebnis: true    ......................................., false sonst
309   extern bool logp (const cl_RA& a, const cl_RA& b, cl_RA* l);
310
311 // Konversion zu einem C "float".
312 extern float float_approx (const cl_RA& x);
313
314 // Konversion zu einem C "double".
315 extern double double_approx (const cl_RA& x);
316
317
318 // This could be optimized to use in-place operations.
319 inline cl_RA& operator+= (cl_RA& x, const cl_RA& y) { return x = x + y; }
320 inline cl_RA& operator+= (cl_RA& x, const int y) { return x = x + y; }
321 inline cl_RA& operator+= (cl_RA& x, const unsigned int y) { return x = x + y; }
322 inline cl_RA& operator+= (cl_RA& x, const long y) { return x = x + y; }
323 inline cl_RA& operator+= (cl_RA& x, const unsigned long y) { return x = x + y; }
324 #ifdef HAVE_LONGLONG
325 inline cl_RA& operator+= (cl_RA& x, const long long y) { return x = x + y; }
326 inline cl_RA& operator+= (cl_RA& x, const unsigned long long y) { return x = x + y; }
327 #endif
328 inline cl_RA& operator++ /* prefix */ (cl_RA& x) { return x = plus1(x); }
329 inline void operator++ /* postfix */ (cl_RA& x, int dummy) { (void)dummy; x = plus1(x); }
330 inline cl_RA& operator-= (cl_RA& x, const cl_RA& y) { return x = x - y; }
331 inline cl_RA& operator-= (cl_RA& x, const int y) { return x = x - y; }
332 inline cl_RA& operator-= (cl_RA& x, const unsigned int y) { return x = x - y; }
333 inline cl_RA& operator-= (cl_RA& x, const long y) { return x = x - y; }
334 inline cl_RA& operator-= (cl_RA& x, const unsigned long y) { return x = x - y; }
335 #ifdef HAVE_LONGLONG
336 inline cl_RA& operator-= (cl_RA& x, const long long y) { return x = x - y; }
337 inline cl_RA& operator-= (cl_RA& x, const unsigned long long y) { return x = x - y; }
338 #endif
339 inline cl_RA& operator-- /* prefix */ (cl_RA& x) { return x = minus1(x); }
340 inline void operator-- /* postfix */ (cl_RA& x, int dummy) { (void)dummy; x = minus1(x); }
341 inline cl_RA& operator*= (cl_RA& x, const cl_RA& y) { return x = x * y; }
342 inline cl_RA& operator/= (cl_RA& x, const cl_RA& y) { return x = x / y; }
343
344
345 // Runtime typing support.
346 extern cl_class cl_class_ratio;
347
348
349 // Debugging support.
350 #ifdef CL_DEBUG
351 extern int cl_RA_debug_module;
352 CL_FORCE_LINK(cl_RA_debug_dummy, cl_RA_debug_module)
353 #endif
354
355 }  // namespace cln
356
357 #endif /* _CL_RATIONAL_H */