]> www.ginac.de Git - cln.git/blob - src/rational/cl_RA.h
Initial revision
[cln.git] / src / rational / cl_RA.h
1 // cl_RA internals
2
3 #ifndef _CL_RA_H
4 #define _CL_RA_H
5
6 #include "cl_number.h"
7 #include "cl_rational.h"
8 #include "cl_macros.h"
9 #include "cl_malloc.h"
10 #include "cl_I.h"
11
12 struct cl_heap_ratio : cl_heap {
13         cl_I numerator;
14         cl_I denominator;
15 };
16
17 inline cl_heap_ratio* TheRatio (cl_heap_ratio* p)
18         { return p; }
19 inline cl_heap_ratio* TheRatio (const cl_number& obj)
20         { return (cl_heap_ratio*)(obj.pointer); }
21
22 inline cl_heap_ratio* allocate_ratio (const cl_I& num, const cl_I& den)
23 {
24         cl_heap_ratio* p = (cl_heap_ratio*) cl_malloc_hook(sizeof(cl_heap_ratio));
25         p->refcount = 1;
26         p->type = &cl_class_ratio;
27         p->numerator.pointer = num.pointer;     cl_inc_refcount(num);
28         p->denominator.pointer = den.pointer;   cl_inc_refcount(den);
29         return p;
30 }
31
32 // Private constructor.
33 // ptr should be the result of some allocate_ratio() call.
34 inline cl_RA::cl_RA (cl_heap_ratio* ptr)
35         : cl_R ((cl_private_thing) ptr) {}
36
37 // Both work, but the first definition results in less compiler-generated
38 // temporaries.
39 #if 1
40   #define Ratio  cl_heap_ratio*
41 #else
42   #define Ratio  cl_RA
43 #endif
44
45 // Type tests.
46 inline cl_boolean rationalp (const cl_RA& x)
47         { unused x; return cl_true; }
48 inline cl_boolean integerp (const cl_RA& x)
49 {
50         if (!x.pointer_p())
51                 return cl_true;
52         else
53                 if (x.pointer_type() == &cl_class_bignum)
54                         return cl_true;
55         return cl_false;
56 }
57 inline cl_boolean ratiop (const cl_RA& x)
58 {
59         if (!x.pointer_p())
60                 return cl_false;
61         else
62                 if (x.pointer_type() == &cl_class_bignum)
63                         return cl_false;
64         return cl_true;
65 }
66
67
68 // A ratio (cl_RT) is a rational number which is not an integer (cl_I).
69
70 // typedef
71 class cl_RT : public cl_RA {
72 public:
73 };
74
75 inline cl_boolean integerp (const cl_RT& x)
76         { unused x; return cl_false; }
77 inline cl_boolean ratiop (const cl_RT& x)
78         { unused x; return cl_true; }
79
80 // Access numerator and denominator.
81 inline const cl_I& numerator (const cl_RT& x)
82         { return TheRatio(x)->numerator; }
83 inline const cl_I& denominator (const cl_RT& x)
84         { return TheRatio(x)->denominator; }
85
86
87 // Sign test:
88
89 // (MINUSP x) == (< x 0)
90 inline cl_boolean minusp (const cl_RT& x)
91         { return minusp(numerator(x)); }
92 inline cl_boolean minusp (const cl_RA& x)
93 {
94         if (ratiop(x)) {
95                 DeclareType(cl_RT,x);
96                 return minusp(x);
97         } else {
98                 DeclareType(cl_I,x);
99                 return minusp(x);
100         }
101 }
102
103 // (ZEROP x) == (= x 0)
104 inline cl_boolean zerop (const cl_RT& x)
105         { unused x; return cl_false; }
106 inline cl_boolean zerop (const cl_RA& x)
107 {
108         return (cl_boolean)(x.word == cl_combine(cl_FN_tag,0));
109 }
110
111 // (EQ x y) == (= x y), assuming y a fixnum
112 inline cl_boolean eq (const cl_RA& x, sint32 y)
113 {
114         return (cl_boolean)(x.word == cl_combine(cl_FN_tag,y));
115 }
116
117 // Liefert zu den Integers a und b mit b>1 und ggT(a,b)=1 den Bruch a/b.
118 // I_I_to_RT(a,b)
119   extern const cl_RA I_I_to_RT (const cl_I& a, const cl_I& b);
120
121 // Liefert zu den Integers a und b mit b>0 und ggT(a,b)=1 den Bruch a/b
122 // (Ratio oder Integer).
123 // I_I_to_RA(a,b)
124   extern const cl_RA I_I_to_RA (const cl_I& a, const cl_I& b);
125
126 // Liefert zu den Integers a und b mit b>0 den Bruch a/b (Ratio oder Integer).
127 // I_posI_div_RA(a,b)
128   extern const cl_RA I_posI_div_RA (const cl_I& a, const cl_I& b);
129
130 // Liefert zu den Integers a und b den Bruch a/b (Ratio oder Integer).
131 // I_I_div_RA(a,b)
132   extern const cl_RA I_I_div_RA (const cl_I& a, const cl_I& b);
133
134 // Liefert den Zähler einer rationalen Zahl.
135 // numerator(r)
136 inline const cl_I numerator (const cl_RA& r)
137 {
138         if (integerp(r)) {
139                 DeclareType(cl_I,r);
140                 return r;
141         } else
142                 return TheRatio(r)->numerator;
143 }
144
145 // Liefert den Nenner einer rationalen Zahl.
146 // denominator(r)
147 inline const cl_I denominator (const cl_RA& r)
148 {
149         if (integerp(r))
150                 return 1;
151         else
152                 return TheRatio(r)->denominator;
153 }
154
155 // Liefert Zähler und Nenner einer rationalen Zahl.
156 // RA_numden_I_I(r, num=,den=);
157 // > r: rationale Zahl
158 // < num: (numerator r)
159 // < den: (denominator r)
160   #define RA_numden_I_I(r,num_zuweisung,den_zuweisung)  \
161     { if (integerp(r))                                                  \
162         { num_zuweisung *(const cl_I *)&r;                              \
163           den_zuweisung 1; /* Zähler = r, Nenner = 1 */                 \
164         }                                                               \
165         else                                                            \
166         { num_zuweisung TheRatio(r)->numerator;                         \
167           den_zuweisung TheRatio(r)->denominator;                       \
168         }                                                               \
169     }
170
171
172 #endif /* _CL_RA_H */