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.

413 lines
13 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
25 years ago
25 years ago
25 years ago
  1. // Public long float operations.
  2. #ifndef _CL_LFLOAT_H
  3. #define _CL_LFLOAT_H
  4. #include "cln/number.h"
  5. #include "cln/lfloat_class.h"
  6. #include "cln/integer_class.h"
  7. #include "cln/float.h"
  8. namespace cln {
  9. CL_DEFINE_AS_CONVERSION(cl_LF)
  10. // Liefert zu einem Long-Float x : (- x), ein LF.
  11. extern const cl_LF operator- (const cl_LF& x);
  12. // compare(x,y) vergleicht zwei Long-Floats x und y.
  13. // Ergebnis: 0 falls x=y, +1 falls x>y, -1 falls x<y.
  14. extern cl_signean compare (const cl_LF& x, const cl_LF& y);
  15. // equal_hashcode(x) liefert einen equal-invarianten Hashcode f�r x.
  16. extern uint32 equal_hashcode (const cl_LF& x);
  17. inline bool operator== (const cl_LF& x, const cl_LF& y)
  18. { return compare(x,y)==0; }
  19. inline bool operator!= (const cl_LF& x, const cl_LF& y)
  20. { return compare(x,y)!=0; }
  21. inline bool operator<= (const cl_LF& x, const cl_LF& y)
  22. { return compare(x,y)<=0; }
  23. inline bool operator< (const cl_LF& x, const cl_LF& y)
  24. { return compare(x,y)<0; }
  25. inline bool operator>= (const cl_LF& x, const cl_LF& y)
  26. { return compare(x,y)>=0; }
  27. inline bool operator> (const cl_LF& x, const cl_LF& y)
  28. { return compare(x,y)>0; }
  29. // minusp(x) == (< x 0)
  30. extern cl_boolean minusp (const cl_LF& x);
  31. // zerop(x) stellt fest, ob ein Long-Float x = 0.0 ist.
  32. extern cl_boolean zerop (const cl_LF& x);
  33. // plusp(x) == (> x 0)
  34. extern cl_boolean plusp (const cl_LF& x);
  35. // Liefert zu zwei Long-Float x und y : (+ x y), ein LF.
  36. extern const cl_LF operator+ (const cl_LF& x, const cl_LF& y);
  37. // Liefert zu zwei Long-Float x und y : (- x y), ein LF.
  38. extern const cl_LF operator- (const cl_LF& x, const cl_LF& y);
  39. // Liefert zu zwei Long-Float x und y : (* x y), ein LF.
  40. extern const cl_LF operator* (const cl_LF& x, const cl_LF& y);
  41. // Spezialfall x oder y Integer oder rationale Zahl.
  42. inline const cl_R operator* (const cl_LF& x, const cl_I& y)
  43. {
  44. extern const cl_R cl_LF_I_mul (const cl_LF&, const cl_I&);
  45. return cl_LF_I_mul(x,y);
  46. }
  47. inline const cl_R operator* (const cl_I& x, const cl_LF& y)
  48. {
  49. extern const cl_R cl_LF_I_mul (const cl_LF&, const cl_I&);
  50. return cl_LF_I_mul(y,x);
  51. }
  52. inline const cl_R operator* (const cl_LF& x, const cl_RA& y)
  53. {
  54. extern const cl_R cl_LF_RA_mul (const cl_LF&, const cl_RA&);
  55. return cl_LF_RA_mul(x,y);
  56. }
  57. inline const cl_R operator* (const cl_RA& x, const cl_LF& y)
  58. {
  59. extern const cl_R cl_LF_RA_mul (const cl_LF&, const cl_RA&);
  60. return cl_LF_RA_mul(y,x);
  61. }
  62. // Dem C++-Compiler mu� man auch das Folgende sagen (wg. `int * cl_LF' u.�.):
  63. inline const cl_R operator* (const int x, const cl_LF& y)
  64. { return cl_I(x) * y; }
  65. inline const cl_R operator* (const unsigned int x, const cl_LF& y)
  66. { return cl_I(x) * y; }
  67. inline const cl_R operator* (const long x, const cl_LF& y)
  68. { return cl_I(x) * y; }
  69. inline const cl_R operator* (const unsigned long x, const cl_LF& y)
  70. { return cl_I(x) * y; }
  71. inline const cl_R operator* (const cl_LF& x, const int y)
  72. { return x * cl_I(y); }
  73. inline const cl_R operator* (const cl_LF& x, const unsigned int y)
  74. { return x * cl_I(y); }
  75. inline const cl_R operator* (const cl_LF& x, const long y)
  76. { return x * cl_I(y); }
  77. inline const cl_R operator* (const cl_LF& x, const unsigned long y)
  78. { return x * cl_I(y); }
  79. // Spezialfall x = y.
  80. // Liefert zu einem Long-Float x : (* x x), ein LF.
  81. extern const cl_LF square (const cl_LF& x);
  82. // Liefert zu zwei Long-Float x und y : (/ x y), ein LF.
  83. extern const cl_LF operator/ (const cl_LF& x, const cl_LF& y);
  84. // Spezialfall x oder y Integer oder rationale Zahl.
  85. inline const cl_LF operator/ (const cl_LF& x, const cl_I& y)
  86. {
  87. extern const cl_LF cl_LF_I_div (const cl_LF& x, const cl_I& y);
  88. return cl_LF_I_div(x,y);
  89. }
  90. inline const cl_R operator/ (const cl_I& x, const cl_LF& y)
  91. {
  92. extern const cl_R cl_I_LF_div (const cl_I& x, const cl_LF& y);
  93. return cl_I_LF_div(x,y);
  94. }
  95. inline const cl_LF operator/ (const cl_LF& x, const cl_RA& y)
  96. {
  97. extern const cl_LF cl_LF_RA_div (const cl_LF& x, const cl_RA& y);
  98. return cl_LF_RA_div(x,y);
  99. }
  100. inline const cl_R operator/ (const cl_RA& x, const cl_LF& y)
  101. {
  102. extern const cl_R cl_RA_LF_div (const cl_RA& x, const cl_LF& y);
  103. return cl_RA_LF_div(x,y);
  104. }
  105. // Dem C++-Compiler mu� man nun auch das Folgende sagen:
  106. inline const cl_LF operator/ (const cl_LF& x, const int y)
  107. { return x / cl_I(y); }
  108. inline const cl_LF operator/ (const cl_LF& x, const unsigned int y)
  109. { return x / cl_I(y); }
  110. inline const cl_LF operator/ (const cl_LF& x, const long y)
  111. { return x / cl_I(y); }
  112. inline const cl_LF operator/ (const cl_LF& x, const unsigned long y)
  113. { return x / cl_I(y); }
  114. inline const cl_R operator/ (const int x, const cl_LF& y)
  115. { return cl_I(x) / y; }
  116. inline const cl_R operator/ (const unsigned int x, const cl_LF& y)
  117. { return cl_I(x) / y; }
  118. inline const cl_R operator/ (const long x, const cl_LF& y)
  119. { return cl_I(x) / y; }
  120. inline const cl_R operator/ (const unsigned long x, const cl_LF& y)
  121. { return cl_I(x) / y; }
  122. // Liefert zu einem Long-Float x>=0 : (sqrt x), ein LF.
  123. extern const cl_LF sqrt (const cl_LF& x);
  124. // recip(x) liefert (/ x), wo x ein Long-Float ist.
  125. extern const cl_LF recip (const cl_LF& x);
  126. // abs(x) liefert (abs x), wo x ein Long-Float ist.
  127. extern const cl_LF abs (const cl_LF& x);
  128. // (1+ x), wo x ein Long-Float ist.
  129. extern const cl_LF plus1 (const cl_LF& x);
  130. // (1- x), wo x ein Long-Float ist.
  131. extern const cl_LF minus1 (const cl_LF& x);
  132. // ffloor(x) liefert (ffloor x), wo x ein LF ist.
  133. extern const cl_LF ffloor (const cl_LF& x);
  134. // fceiling(x) liefert (fceiling x), wo x ein LF ist.
  135. extern const cl_LF fceiling (const cl_LF& x);
  136. // ftruncate(x) liefert (ftruncate x), wo x ein LF ist.
  137. extern const cl_LF ftruncate (const cl_LF& x);
  138. // fround(x) liefert (fround x), wo x ein LF ist.
  139. extern const cl_LF fround (const cl_LF& x);
  140. // Return type for frounding operators.
  141. // x / y --> (q,r) with x = y*q+r.
  142. struct cl_LF_fdiv_t {
  143. cl_LF quotient;
  144. cl_LF remainder;
  145. // Constructor.
  146. cl_LF_fdiv_t () {}
  147. cl_LF_fdiv_t (const cl_LF& q, const cl_LF& r) : quotient(q), remainder(r) {}
  148. };
  149. // ffloor2(x) liefert (ffloor x), wo x ein LF ist.
  150. inline const cl_LF_fdiv_t ffloor2 (const cl_LF& x)
  151. {
  152. extern const cl_LF LF_LF_minus_LF (const cl_LF&, const cl_LF&);
  153. cl_LF q = ffloor(x);
  154. return cl_LF_fdiv_t(q,LF_LF_minus_LF(x,q));
  155. }
  156. // fceiling2(x) liefert (fceiling x), wo x ein LF ist.
  157. inline const cl_LF_fdiv_t fceiling2 (const cl_LF& x)
  158. {
  159. extern const cl_LF LF_LF_minus_LF (const cl_LF&, const cl_LF&);
  160. cl_LF q = fceiling(x);
  161. return cl_LF_fdiv_t(q,LF_LF_minus_LF(x,q));
  162. }
  163. // ftruncate2(x) liefert (ftruncate x), wo x ein LF ist.
  164. inline const cl_LF_fdiv_t ftruncate2 (const cl_LF& x)
  165. {
  166. extern const cl_LF LF_LF_minus_LF (const cl_LF&, const cl_LF&);
  167. cl_LF q = ftruncate(x);
  168. return cl_LF_fdiv_t(q,LF_LF_minus_LF(x,q));
  169. }
  170. // fround2(x) liefert (fround x), wo x ein LF ist.
  171. inline const cl_LF_fdiv_t fround2 (const cl_LF& x)
  172. {
  173. extern const cl_LF LF_LF_minus_LF (const cl_LF&, const cl_LF&);
  174. cl_LF q = fround(x);
  175. return cl_LF_fdiv_t(q,LF_LF_minus_LF(x,q));
  176. }
  177. // Return type for rounding operators.
  178. // x / y --> (q,r) with x = y*q+r.
  179. struct cl_LF_div_t {
  180. cl_I quotient;
  181. cl_LF remainder;
  182. // Constructor.
  183. cl_LF_div_t () {}
  184. cl_LF_div_t (const cl_I& q, const cl_LF& r) : quotient(q), remainder(r) {}
  185. };
  186. // floor2(x) liefert (floor x), wo x ein LF ist.
  187. inline const cl_LF_div_t floor2 (const cl_LF& x)
  188. {
  189. extern const cl_LF LF_LF_minus_LF (const cl_LF&, const cl_LF&);
  190. extern const cl_I cl_LF_to_I (const cl_LF& x);
  191. cl_LF q = ffloor(x);
  192. return cl_LF_div_t(cl_LF_to_I(q),LF_LF_minus_LF(x,q));
  193. }
  194. inline const cl_I floor1 (const cl_LF& x)
  195. {
  196. extern const cl_I cl_LF_to_I (const cl_LF& x);
  197. return cl_LF_to_I(ffloor(x));
  198. }
  199. // ceiling2(x) liefert (ceiling x), wo x ein LF ist.
  200. inline const cl_LF_div_t ceiling2 (const cl_LF& x)
  201. {
  202. extern const cl_LF LF_LF_minus_LF (const cl_LF&, const cl_LF&);
  203. extern const cl_I cl_LF_to_I (const cl_LF& x);
  204. cl_LF q = fceiling(x);
  205. return cl_LF_div_t(cl_LF_to_I(q),LF_LF_minus_LF(x,q));
  206. }
  207. inline const cl_I ceiling1 (const cl_LF& x)
  208. {
  209. extern const cl_I cl_LF_to_I (const cl_LF& x);
  210. return cl_LF_to_I(fceiling(x));
  211. }
  212. // truncate2(x) liefert (truncate x), wo x ein LF ist.
  213. inline const cl_LF_div_t truncate2 (const cl_LF& x)
  214. {
  215. extern const cl_LF LF_LF_minus_LF (const cl_LF&, const cl_LF&);
  216. extern const cl_I cl_LF_to_I (const cl_LF& x);
  217. cl_LF q = ftruncate(x);
  218. return cl_LF_div_t(cl_LF_to_I(q),LF_LF_minus_LF(x,q));
  219. }
  220. inline const cl_I truncate1 (const cl_LF& x)
  221. {
  222. extern const cl_I cl_LF_to_I (const cl_LF& x);
  223. return cl_LF_to_I(ftruncate(x));
  224. }
  225. // round2(x) liefert (round x), wo x ein LF ist.
  226. inline const cl_LF_div_t round2 (const cl_LF& x)
  227. {
  228. extern const cl_LF LF_LF_minus_LF (const cl_LF&, const cl_LF&);
  229. extern const cl_I cl_LF_to_I (const cl_LF& x);
  230. cl_LF q = fround(x);
  231. return cl_LF_div_t(cl_LF_to_I(q),LF_LF_minus_LF(x,q));
  232. }
  233. inline const cl_I round1 (const cl_LF& x)
  234. {
  235. extern const cl_I cl_LF_to_I (const cl_LF& x);
  236. return cl_LF_to_I(fround(x));
  237. }
  238. // floor2(x,y) liefert (floor x y).
  239. extern const cl_LF_div_t floor2 (const cl_LF& x, const cl_LF& y);
  240. inline const cl_I floor1 (const cl_LF& x, const cl_LF& y) { return floor1(x/y); }
  241. // ceiling2(x,y) liefert (ceiling x y).
  242. extern const cl_LF_div_t ceiling2 (const cl_LF& x, const cl_LF& y);
  243. inline const cl_I ceiling1 (const cl_LF& x, const cl_LF& y) { return ceiling1(x/y); }
  244. // truncate2(x,y) liefert (truncate x y).
  245. extern const cl_LF_div_t truncate2 (const cl_LF& x, const cl_LF& y);
  246. inline const cl_I truncate1 (const cl_LF& x, const cl_LF& y) { return truncate1(x/y); }
  247. // round2(x,y) liefert (round x y).
  248. extern const cl_LF_div_t round2 (const cl_LF& x, const cl_LF& y);
  249. inline const cl_I round1 (const cl_LF& x, const cl_LF& y) { return round1(x/y); }
  250. // cl_float(x,y) returns a long float if y is a long float.
  251. inline const cl_LF cl_float (const cl_F& x, const cl_LF& y)
  252. {
  253. extern const cl_F cl_float (const cl_F& x, const cl_F& y);
  254. return The(cl_LF)(cl_float(x,(const cl_F&)y));
  255. }
  256. inline const cl_LF cl_float (const cl_I& x, const cl_LF& y)
  257. {
  258. extern const cl_F cl_float (const cl_I& x, const cl_F& y);
  259. return The(cl_LF)(cl_float(x,(const cl_F&)y));
  260. }
  261. inline const cl_LF cl_float (const cl_RA& x, const cl_LF& y)
  262. {
  263. extern const cl_F cl_float (const cl_RA& x, const cl_F& y);
  264. return The(cl_LF)(cl_float(x,(const cl_F&)y));
  265. }
  266. inline const cl_LF cl_float (int x, const cl_LF& y)
  267. { return cl_float(cl_I(x),y); }
  268. inline const cl_LF cl_float (unsigned int x, const cl_LF& y)
  269. { return cl_float(cl_I(x),y); }
  270. // Return type for decode_float:
  271. struct decoded_lfloat {
  272. cl_LF mantissa;
  273. cl_I exponent;
  274. cl_LF sign;
  275. // Constructor.
  276. decoded_lfloat () {}
  277. decoded_lfloat (const cl_LF& m, const cl_I& e, const cl_LF& s) : mantissa(m), exponent(e), sign(s) {}
  278. };
  279. // decode_float(x) liefert zu einem Float x: (decode-float x).
  280. // x = 0.0 liefert (0.0, 0, 1.0).
  281. // x = (-1)^s * 2^e * m liefert ((-1)^0 * 2^0 * m, e als Integer, (-1)^s).
  282. extern const decoded_lfloat decode_float (const cl_LF& x);
  283. // float_exponent(x) liefert zu einem Float x:
  284. // den Exponenten von (decode-float x).
  285. // x = 0.0 liefert 0.
  286. // x = (-1)^s * 2^e * m liefert e.
  287. extern sintL float_exponent (const cl_LF& x);
  288. // float_radix(x) liefert (float-radix x), wo x ein Float ist.
  289. inline sintL float_radix (const cl_LF& x)
  290. {
  291. (void)x; // unused x
  292. return 2;
  293. }
  294. // float_sign(x) liefert (float-sign x), wo x ein Float ist.
  295. extern const cl_LF float_sign (const cl_LF& x);
  296. // float_digits(x) liefert (float-digits x), wo x ein Float ist.
  297. // < ergebnis: ein uintL >0
  298. extern uintL float_digits (const cl_LF& x);
  299. // float_precision(x) liefert (float-precision x), wo x ein Float ist.
  300. // < ergebnis: ein uintL >=0
  301. extern uintL float_precision (const cl_LF& x);
  302. // integer_decode_float(x) liefert zu einem Float x: (integer-decode-float x).
  303. // x = 0.0 liefert (0, 0, 1).
  304. // x = (-1)^s * 2^e * m bei Float-Precision p liefert
  305. // (Mantisse 2^p * m als Integer, e-p als Integer, (-1)^s als Fixnum).
  306. extern const cl_idecoded_float integer_decode_float (const cl_LF& x);
  307. // scale_float(x,delta) liefert x*2^delta, wo x ein LF ist.
  308. extern const cl_LF scale_float (const cl_LF& x, sintL delta);
  309. extern const cl_LF scale_float (const cl_LF& x, const cl_I& delta);
  310. // max(x,y) liefert (max x y), wo x und y Floats sind.
  311. extern const cl_LF max (const cl_LF& x, const cl_LF& y);
  312. // min(x,y) liefert (min x y), wo x und y Floats sind.
  313. extern const cl_LF min (const cl_LF& x, const cl_LF& y);
  314. // signum(x) liefert (signum x), wo x ein Float ist.
  315. extern const cl_LF signum (const cl_LF& x);
  316. // Konversion zu einem C "float".
  317. extern float float_approx (const cl_LF& x);
  318. // Konversion zu einem C "double".
  319. extern double double_approx (const cl_LF& x);
  320. #ifdef WANT_OBFUSCATING_OPERATORS
  321. // This could be optimized to use in-place operations.
  322. inline cl_LF& operator+= (cl_LF& x, const cl_LF& y) { return x = x + y; }
  323. inline cl_LF& operator++ /* prefix */ (cl_LF& x) { return x = plus1(x); }
  324. inline void operator++ /* postfix */ (cl_LF& x, int dummy) { (void)dummy; x = plus1(x); }
  325. inline cl_LF& operator-= (cl_LF& x, const cl_LF& y) { return x = x - y; }
  326. inline cl_LF& operator-- /* prefix */ (cl_LF& x) { return x = minus1(x); }
  327. inline void operator-- /* postfix */ (cl_LF& x, int dummy) { (void)dummy; x = minus1(x); }
  328. inline cl_LF& operator*= (cl_LF& x, const cl_LF& y) { return x = x * y; }
  329. inline cl_LF& operator/= (cl_LF& x, const cl_LF& y) { return x = x / y; }
  330. #endif
  331. // Runtime typing support.
  332. extern cl_class cl_class_lfloat;
  333. // Debugging support.
  334. #ifdef CL_DEBUG
  335. extern int cl_LF_debug_module;
  336. static void* const cl_LF_debug_dummy[] = { &cl_LF_debug_dummy,
  337. &cl_LF_debug_module
  338. };
  339. #endif
  340. } // namespace cln
  341. #endif /* _CL_LFLOAT_H */