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.

304 lines
12 KiB

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