You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

302 lines
12 KiB

25 years ago
  1. // Public rational number operations.
  2. #ifndef _CL_RATIONAL_H
  3. #define _CL_RATIONAL_H
  4. #include "cl_number.h"
  5. #include "cl_rational_class.h"
  6. #include "cl_integer_class.h"
  7. CL_DEFINE_AS_CONVERSION(cl_RA)
  8. // numerator(r) liefert den Z�hler der rationalen Zahl r.
  9. extern const cl_I numerator (const cl_RA& r);
  10. // denominator(r) liefert den Nenner (> 0) der rationalen Zahl r.
  11. extern const cl_I denominator (const cl_RA& r);
  12. // Liefert (- r), wo r eine rationale Zahl ist.
  13. extern const cl_RA operator- (const cl_RA& r);
  14. // (+ r s), wo r und s rationale Zahlen sind.
  15. extern const cl_RA operator+ (const cl_RA& r, const cl_RA& s);
  16. // Dem C++-Compiler mu� man auch das Folgende sagen:
  17. inline const cl_RA operator+ (const int x, const cl_RA& y)
  18. { return cl_I(x) + y; }
  19. inline const cl_RA operator+ (const unsigned int x, const cl_RA& y)
  20. { return cl_I(x) + y; }
  21. inline const cl_RA operator+ (const long x, const cl_RA& y)
  22. { return cl_I(x) + y; }
  23. inline const cl_RA operator+ (const unsigned long x, const cl_RA& y)
  24. { return cl_I(x) + y; }
  25. inline const cl_RA operator+ (const cl_RA& x, const int y)
  26. { return x + cl_I(y); }
  27. inline const cl_RA operator+ (const cl_RA& x, const unsigned int y)
  28. { return x + cl_I(y); }
  29. inline const cl_RA operator+ (const cl_RA& x, const long y)
  30. { return x + cl_I(y); }
  31. inline const cl_RA operator+ (const cl_RA& x, const unsigned long y)
  32. { return x + cl_I(y); }
  33. // (- r s), wo r und s rationale Zahlen sind.
  34. extern const cl_RA operator- (const cl_RA& r, const cl_RA& s);
  35. // Dem C++-Compiler mu� man auch das Folgende sagen:
  36. inline const cl_RA operator- (const int x, const cl_RA& y)
  37. { return cl_I(x) - y; }
  38. inline const cl_RA operator- (const unsigned int x, const cl_RA& y)
  39. { return cl_I(x) - y; }
  40. inline const cl_RA operator- (const long x, const cl_RA& y)
  41. { return cl_I(x) - y; }
  42. inline const cl_RA operator- (const unsigned long x, const cl_RA& y)
  43. { return cl_I(x) - y; }
  44. inline const cl_RA operator- (const cl_RA& x, const int y)
  45. { return x - cl_I(y); }
  46. inline const cl_RA operator- (const cl_RA& x, const unsigned int y)
  47. { return x - cl_I(y); }
  48. inline const cl_RA operator- (const cl_RA& x, const long y)
  49. { return x - cl_I(y); }
  50. inline const cl_RA operator- (const cl_RA& x, const unsigned long y)
  51. { return x - cl_I(y); }
  52. // (1+ r), wo r eine rationale Zahl ist.
  53. extern const cl_RA plus1 (const cl_RA& r);
  54. // (1- r), wo r eine rationale Zahl ist.
  55. extern const cl_RA minus1 (const cl_RA& r);
  56. // (abs r), wo r eine rationale Zahl ist.
  57. extern const cl_RA abs (const cl_RA& r);
  58. // cl_equal(r,s) vergleicht zwei rationale Zahlen r und s auf Gleichheit.
  59. extern cl_boolean cl_equal (const cl_RA& r, const cl_RA& s);
  60. // cl_equal_hashcode(r) liefert einen cl_equal-invarianten Hashcode f�r r.
  61. extern uint32 cl_equal_hashcode (const cl_RA& r);
  62. // cl_compare(r,s) vergleicht zwei rationale Zahlen r und s.
  63. // Ergebnis: 0 falls r=s, +1 falls r>s, -1 falls r<s.
  64. extern cl_signean cl_compare (const cl_RA& r, const cl_RA& s);
  65. inline bool operator== (const cl_RA& x, const cl_RA& y)
  66. { return cl_equal(x,y); }
  67. inline bool operator!= (const cl_RA& x, const cl_RA& y)
  68. { return !cl_equal(x,y); }
  69. inline bool operator<= (const cl_RA& x, const cl_RA& y)
  70. { return cl_compare(x,y)<=0; }
  71. inline bool operator< (const cl_RA& x, const cl_RA& y)
  72. { return cl_compare(x,y)<0; }
  73. inline bool operator>= (const cl_RA& x, const cl_RA& y)
  74. { return cl_compare(x,y)>=0; }
  75. inline bool operator> (const cl_RA& x, const cl_RA& y)
  76. { return cl_compare(x,y)>0; }
  77. // minusp(x) == (< x 0)
  78. extern cl_boolean minusp (const cl_RA& x);
  79. // zerop(x) stellt fest, ob eine rationale Zahl = 0 ist.
  80. extern cl_boolean zerop (const cl_RA& x);
  81. // plusp(x) == (> x 0)
  82. extern cl_boolean plusp (const cl_RA& x);
  83. // Kehrwert (/ r), wo r eine rationale Zahl ist.
  84. extern const cl_RA recip (const cl_RA& r);
  85. // Liefert (* r s), wo r und s rationale Zahlen sind.
  86. extern const cl_RA operator* (const cl_RA& r, const cl_RA& s);
  87. // Dem C++-Compiler mu� man auch das Folgende sagen:
  88. inline const cl_RA operator* (const int x, const cl_RA& y)
  89. { return cl_I(x) * y; }
  90. inline const cl_RA operator* (const unsigned int x, const cl_RA& y)
  91. { return cl_I(x) * y; }
  92. inline const cl_RA operator* (const long x, const cl_RA& y)
  93. { return cl_I(x) * y; }
  94. inline const cl_RA operator* (const unsigned long x, const cl_RA& y)
  95. { return cl_I(x) * y; }
  96. inline const cl_RA operator* (const cl_RA& x, const int y)
  97. { return x * cl_I(y); }
  98. inline const cl_RA operator* (const cl_RA& x, const unsigned int y)
  99. { return x * cl_I(y); }
  100. inline const cl_RA operator* (const cl_RA& x, const long y)
  101. { return x * cl_I(y); }
  102. inline const cl_RA operator* (const cl_RA& x, const unsigned long y)
  103. { return x * cl_I(y); }
  104. // Quadrat (* r r), wo r eine rationale Zahl ist.
  105. extern const cl_RA square (const cl_RA& r);
  106. // Liefert (/ r s), wo r und s rationale Zahlen sind.
  107. extern const cl_RA operator/ (const cl_RA& r, const cl_RA& s);
  108. // Dem C++-Compiler mu� man auch das Folgende sagen:
  109. inline const cl_RA operator/ (const int x, const cl_RA& y)
  110. { return cl_I(x) / y; }
  111. inline const cl_RA operator/ (const unsigned int x, const cl_RA& y)
  112. { return cl_I(x) / y; }
  113. inline const cl_RA operator/ (const long x, const cl_RA& y)
  114. { return cl_I(x) / y; }
  115. inline const cl_RA operator/ (const unsigned long x, const cl_RA& y)
  116. { return cl_I(x) / y; }
  117. inline const cl_RA operator/ (const cl_RA& x, const int y)
  118. { return x / cl_I(y); }
  119. inline const cl_RA operator/ (const cl_RA& x, const unsigned int y)
  120. { return x / cl_I(y); }
  121. inline const cl_RA operator/ (const cl_RA& x, const long y)
  122. { return x / cl_I(y); }
  123. inline const cl_RA operator/ (const cl_RA& x, const unsigned long y)
  124. { return x / cl_I(y); }
  125. // Return type for rounding operators.
  126. // x / y --> (q,r) with x = y*q+r.
  127. struct cl_RA_div_t {
  128. cl_I quotient;
  129. cl_RA remainder;
  130. // Constructor.
  131. cl_RA_div_t () {}
  132. cl_RA_div_t (const cl_I& q, const cl_RA& r) : quotient(q), remainder(r) {}
  133. };
  134. // Liefert ganzzahligen und gebrochenen Anteil einer rationalen Zahl.
  135. // (q,r) := (floor x)
  136. // floor2(x)
  137. // > x: rationale Zahl
  138. // < q,r: Quotient q, ein Integer, Rest r, eine rationale Zahl
  139. extern const cl_RA_div_t floor2 (const cl_RA& x);
  140. extern const cl_I floor1 (const cl_RA& x);
  141. // Liefert ganzzahligen und gebrochenen Anteil einer rationalen Zahl.
  142. // (q,r) := (ceiling x)
  143. // ceiling2(x)
  144. // > x: rationale Zahl
  145. // < q,r: Quotient q, ein Integer, Rest r, eine rationale Zahl
  146. extern const cl_RA_div_t ceiling2 (const cl_RA& x);
  147. extern const cl_I ceiling1 (const cl_RA& x);
  148. // Liefert ganzzahligen und gebrochenen Anteil einer rationalen Zahl.
  149. // (q,r) := (truncate x)
  150. // truncate2(x)
  151. // > x: rationale Zahl
  152. // < q,r: Quotient q, ein Integer, Rest r, eine rationale Zahl
  153. extern const cl_RA_div_t truncate2 (const cl_RA& x);
  154. extern const cl_I truncate1 (const cl_RA& x);
  155. // Liefert ganzzahligen und gebrochenen Anteil einer rationalen Zahl.
  156. // (q,r) := (round x)
  157. // round2(x)
  158. // > x: rationale Zahl
  159. // < q,r: Quotient q, ein Integer, Rest r, eine rationale Zahl
  160. extern const cl_RA_div_t round2 (const cl_RA& x);
  161. extern const cl_I round1 (const cl_RA& x);
  162. // floor2(x,y) liefert (floor x y).
  163. extern const cl_RA_div_t floor2 (const cl_RA& x, const cl_RA& y);
  164. extern const cl_I floor1 (const cl_RA& x, const cl_RA& y);
  165. // ceiling2(x,y) liefert (ceiling x y).
  166. extern const cl_RA_div_t ceiling2 (const cl_RA& x, const cl_RA& y);
  167. extern const cl_I ceiling1 (const cl_RA& x, const cl_RA& y);
  168. // truncate2(x,y) liefert (truncate x y).
  169. extern const cl_RA_div_t truncate2 (const cl_RA& x, const cl_RA& y);
  170. extern const cl_I truncate1 (const cl_RA& x, const cl_RA& y);
  171. // round2(x,y) liefert (round x y).
  172. extern const cl_RA_div_t round2 (const cl_RA& x, const cl_RA& y);
  173. extern const cl_I round1 (const cl_RA& x, const cl_RA& y);
  174. // max(x,y) liefert (max x y), wo x und y rationale Zahlen sind.
  175. extern const cl_RA max (const cl_RA& x, const cl_RA& y);
  176. // min(x,y) liefert (min x y), wo x und y rationale Zahlen sind.
  177. extern const cl_RA min (const cl_RA& x, const cl_RA& y);
  178. // signum(x) liefert (signum x), wo x eine rationale Zahl ist.
  179. extern const cl_RA signum (const cl_RA& x);
  180. // (expt x y), wo x eine rationale Zahl und y ein Integer >0 ist.
  181. extern const cl_RA expt_pos (const cl_RA& x, uintL y);
  182. extern const cl_RA expt_pos (const cl_RA& x, const cl_I& y);
  183. // (expt x y), wo x eine rationale Zahl und y ein Integer ist.
  184. extern const cl_RA expt (const cl_RA& x, sintL y);
  185. extern const cl_RA expt (const cl_RA& x, const cl_I& y);
  186. // Stellt fest, ob eine rationale Zahl >=0 das Quadrat einer rationalen Zahl
  187. // ist.
  188. // sqrtp(x,&w)
  189. // > x: eine rationale Zahl >=0
  190. // < w: rationale Zahl (sqrt x) falls x Quadratzahl
  191. // < ergebnis: cl_true ..................., cl_false sonst
  192. extern cl_boolean sqrtp (const cl_RA& x, cl_RA* w);
  193. // Stellt fest, ob eine rationale Zahl >=0 die n-te Potenz einer rationalen Zahl
  194. // ist.
  195. // rootp(x,n,&w)
  196. // > x: eine rationale Zahl >=0
  197. // > n: ein Integer >0
  198. // < w: exakte n-te Wurzel (expt x (/ n)) falls x eine n-te Potenz
  199. // < ergebnis: cl_true ........................, cl_false sonst
  200. extern cl_boolean rootp (const cl_RA& x, uintL n, cl_RA* w);
  201. extern cl_boolean rootp (const cl_RA& x, const cl_I& n, cl_RA* w);
  202. // Liefert zu Integers a>0, b>1 den Logarithmus log(a,b),
  203. // falls er eine rationale Zahl ist.
  204. // logp(a,b,&l)
  205. // > a: ein Integer >0
  206. // > b: ein Integer >1
  207. // < l: log(a,b) falls er eine exakte rationale Zahl ist
  208. // < ergebnis: cl_true ......................................., cl_false sonst
  209. extern cl_boolean logp (const cl_I& a, const cl_I& b, cl_RA* l);
  210. // Liefert zu rationalen Zahlen a>0, b>0 den Logarithmus log(a,b),
  211. // falls er eine rationale Zahl ist.
  212. // logp(a,b,&l)
  213. // > a: eine rationale Zahl >0
  214. // > b: eine rationale Zahl >0, /=1
  215. // < l: log(a,b) falls er eine exakte rationale Zahl ist
  216. // < ergebnis: cl_true ......................................., cl_false sonst
  217. extern cl_boolean logp (const cl_RA& a, const cl_RA& b, cl_RA* l);
  218. // Konversion zu einem C "float".
  219. extern float cl_float_approx (const cl_RA& x);
  220. // Konversion zu einem C "double".
  221. extern double cl_double_approx (const cl_RA& x);
  222. #ifdef WANT_OBFUSCATING_OPERATORS
  223. // This could be optimized to use in-place operations.
  224. inline cl_RA& operator+= (cl_RA& x, const cl_RA& y) { return x = x + y; }
  225. inline cl_RA& operator+= (cl_RA& x, const int y) { return x = x + y; }
  226. inline cl_RA& operator+= (cl_RA& x, const unsigned int y) { return x = x + y; }
  227. inline cl_RA& operator+= (cl_RA& x, const long y) { return x = x + y; }
  228. inline cl_RA& operator+= (cl_RA& x, const unsigned long y) { return x = x + y; }
  229. inline cl_RA& operator++ /* prefix */ (cl_RA& x) { return x = plus1(x); }
  230. inline void operator++ /* postfix */ (cl_RA& x, int dummy) { (void)dummy; x = plus1(x); }
  231. inline cl_RA& operator-= (cl_RA& x, const cl_RA& y) { return x = x - y; }
  232. inline cl_RA& operator-= (cl_RA& x, const int y) { return x = x - y; }
  233. inline cl_RA& operator-= (cl_RA& x, const unsigned int y) { return x = x - y; }
  234. inline cl_RA& operator-= (cl_RA& x, const long y) { return x = x - y; }
  235. inline cl_RA& operator-= (cl_RA& x, const unsigned long y) { return x = x - y; }
  236. inline cl_RA& operator-- /* prefix */ (cl_RA& x) { return x = minus1(x); }
  237. inline void operator-- /* postfix */ (cl_RA& x, int dummy) { (void)dummy; x = minus1(x); }
  238. inline cl_RA& operator*= (cl_RA& x, const cl_RA& y) { return x = x * y; }
  239. inline cl_RA& operator/= (cl_RA& x, const cl_RA& y) { return x = x / y; }
  240. #endif
  241. // Runtime typing support.
  242. extern cl_class cl_class_ratio;
  243. // Debugging support.
  244. #ifdef CL_DEBUG
  245. extern int cl_RA_debug_module;
  246. static void* const cl_RA_debug_dummy[] = { &cl_RA_debug_dummy,
  247. &cl_RA_debug_module
  248. };
  249. #endif
  250. #endif /* _CL_RATIONAL_H */