Annotation of OpenXM_contrib/gmp/mpfrxx.h, Revision 1.1.1.1
1.1 ohara 1: /* mpfrxx.h -- C++ class wrapper for MPFR. -*- C++ -*-
2:
3: Copyright 2001, 2002 Free Software Foundation, Inc.
4:
5: This file is part of the GNU MP Library.
6:
7: The GNU MP Library is free software; you can redistribute it and/or modify
8: it under the terms of the GNU Lesser General Public License as published by
9: the Free Software Foundation; either version 2.1 of the License, or (at your
10: option) any later version.
11:
12: The GNU MP Library is distributed in the hope that it will be useful, but
13: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15: License for more details.
16:
17: You should have received a copy of the GNU Lesser General Public License
18: along with the GNU MP Library; see the file COPYING.LIB. If not, write to
19: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20: MA 02111-1307, USA. */
21:
22: #ifndef __GMPFR_PLUSPLUS__
23: #define __GMPFR_PLUSPLUS__
24:
25: #include <iostream>
26: #include <string>
27: #include <gmp.h>
28: #include <mpfr.h>
29: #include "gmpxx.h"
30:
31:
32: class __gmpfr_value { };
33:
34: template <class T, class U>
35: void __gmp_set_expr(mpfr_ptr, const __gmp_expr<T, U> &);
36:
37: const int mpfr_default_base = 10;
38:
39:
40: /**************** Macros for in-class declarations ****************/
41:
42: #define __GMPFRR_DECLARE_COMPOUND_OPERATOR(fun) \
43: template <class T, class U> \
44: __gmp_expr<__gmpfr_value, __gmpfr_value> & fun(const __gmp_expr<T, U> &);
45:
46: #define __GMPFRN_DECLARE_COMPOUND_OPERATOR(fun) \
47: __gmp_expr & fun(signed char); \
48: __gmp_expr & fun(unsigned char); \
49: __gmp_expr & fun(signed int); \
50: __gmp_expr & fun(unsigned int); \
51: __gmp_expr & fun(signed short int); \
52: __gmp_expr & fun(unsigned short int); \
53: __gmp_expr & fun(signed long int); \
54: __gmp_expr & fun(unsigned long int); \
55: __gmp_expr & fun(float); \
56: __gmp_expr & fun(double); \
57: __gmp_expr & fun(long double);
58:
59: #define __GMPFR_DECLARE_COMPOUND_OPERATOR(fun) \
60: __GMPFRR_DECLARE_COMPOUND_OPERATOR(fun) \
61: __GMPFRN_DECLARE_COMPOUND_OPERATOR(fun)
62:
63: #define __GMPFR_DECLARE_COMPOUND_OPERATOR_UI(fun) \
64: __gmp_expr & fun(unsigned long int);
65:
66: #define __GMPFR_DECLARE_INCREMENT_OPERATOR(fun) \
67: inline __gmp_expr & fun(); \
68: inline __gmp_expr fun(int);
69:
70:
71: /**************** mpfr_class -- wrapper for mpfr_t ****************/
72:
73: template <>
74: class __gmp_expr<__gmpfr_value, __gmpfr_value>
75: {
76: private:
77: mpfr_t mp;
78: public:
79: // size information
80: unsigned long int get_prec() const { return mpfr_get_prec(mp); }
81:
82: // constructors and destructor
83: __gmp_expr() { mpfr_init(mp); }
84:
85: __gmp_expr(const __gmp_expr &f)
86: {
87: mpfr_init2(mp, f.get_prec());
88: mpfr_set(mp, f.mp, __gmp_default_rounding_mode);
89: }
90: __gmp_expr(const __gmp_expr &f, unsigned long int prec,
91: mp_rnd_t mode = __gmp_default_rounding_mode)
92: { mpfr_init2(mp, prec); mpfr_set(mp, f.mp, mode); }
93: template <class T, class U>
94: __gmp_expr(const __gmp_expr<T, U> &expr)
95: { mpfr_init2(mp, expr.get_prec()); __gmp_set_expr(mp, expr); }
96: template <class T, class U>
97: __gmp_expr(const __gmp_expr<T, U> &expr, unsigned long int prec)
98: { mpfr_init2(mp, prec); __gmp_set_expr(mp, expr); }
99:
100: __gmp_expr(signed char c)
101: { mpfr_init(mp); mpfr_set_si(mp, c, __gmp_default_rounding_mode); }
102: __gmp_expr(signed char c, unsigned long int prec,
103: mp_rnd_t mode = __gmp_default_rounding_mode)
104: { mpfr_init2(mp, prec); mpfr_set_si(mp, c, mode); }
105: __gmp_expr(unsigned char c)
106: { mpfr_init(mp); mpfr_set_ui(mp, c, __gmp_default_rounding_mode); }
107: __gmp_expr(unsigned char c, unsigned long int prec,
108: mp_rnd_t mode = __gmp_default_rounding_mode)
109: { mpfr_init2(mp, prec); mpfr_set_ui(mp, c, mode); }
110:
111: __gmp_expr(signed int i)
112: { mpfr_init(mp); mpfr_set_si(mp, i, __gmp_default_rounding_mode); }
113: __gmp_expr(signed int i, unsigned long int prec,
114: mp_rnd_t mode = __gmp_default_rounding_mode)
115: { mpfr_init2(mp, prec); mpfr_set_si(mp, i, mode); }
116: __gmp_expr(unsigned int i)
117: { mpfr_init(mp); mpfr_set_ui(mp, i, __gmp_default_rounding_mode); }
118: __gmp_expr(unsigned int i, unsigned long int prec,
119: mp_rnd_t mode = __gmp_default_rounding_mode)
120: { mpfr_init2(mp, prec); mpfr_set_ui(mp, i, mode); }
121:
122: __gmp_expr(signed short int s)
123: { mpfr_init(mp); mpfr_set_si(mp, s, __gmp_default_rounding_mode); }
124: __gmp_expr(signed short int s, unsigned long int prec,
125: mp_rnd_t mode = __gmp_default_rounding_mode)
126: { mpfr_init2(mp, prec); mpfr_set_si(mp, s, mode); }
127: __gmp_expr(unsigned short int s)
128: { mpfr_init(mp); mpfr_set_ui(mp, s, __gmp_default_rounding_mode); }
129: __gmp_expr(unsigned short int s, unsigned long int prec,
130: mp_rnd_t mode = __gmp_default_rounding_mode)
131: { mpfr_init2(mp, prec); mpfr_set_ui(mp, s, mode); }
132:
133: __gmp_expr(signed long int l)
134: { mpfr_init(mp); mpfr_set_si(mp, l, __gmp_default_rounding_mode); }
135: __gmp_expr(signed long int l, unsigned long int prec,
136: mp_rnd_t mode = __gmp_default_rounding_mode)
137: { mpfr_init2(mp, prec); mpfr_set_si(mp, l, mode); }
138: __gmp_expr(unsigned long int l)
139: { mpfr_init(mp); mpfr_set_ui(mp, l, __gmp_default_rounding_mode); }
140: __gmp_expr(unsigned long int l, unsigned long int prec,
141: mp_rnd_t mode = __gmp_default_rounding_mode)
142: { mpfr_init2(mp, prec); mpfr_set_ui(mp, l, mode); }
143:
144: __gmp_expr(float f)
145: { mpfr_init(mp); mpfr_set_d(mp, f, __gmp_default_rounding_mode); }
146: __gmp_expr(float f, unsigned long int prec,
147: mp_rnd_t mode = __gmp_default_rounding_mode)
148: { mpfr_init2(mp, prec); mpfr_set_d(mp, f, mode); }
149: __gmp_expr(double d)
150: { mpfr_init(mp); mpfr_set_d(mp, d, __gmp_default_rounding_mode); }
151: __gmp_expr(double d, unsigned long int prec,
152: mp_rnd_t mode = __gmp_default_rounding_mode)
153: { mpfr_init2(mp, prec); mpfr_set_d(mp, d, mode); }
154: /*
155: __gmp_expr(long double ld)
156: { mpfr_init(mp); mpfr_set_d(mp, ld, __gmp_default_rounding_mode); }
157: __gmp_expr(long double ld, unsigned long int prec,
158: mp_rnd_t mode = __gmp_default_rounding_mode)
159: { mpfr_init2(mp, prec); mpfr_set_d(mp, ld, mode); }
160: */
161:
162: /*
163: explicit __gmp_expr(const char *s)
164: { mpfr_init_set_str(mp, s, mpfr_default_base); }
165: __gmp_expr(const char *s, int base) { mpfr_init_set_str(mp, s, base); }
166: explicit __gmp_expr(const std::string &s)
167: { mpfr_init_set_str(mp, s.c_str(), mpfr_default_base); }
168: __gmp_expr(const std::string &s, int base)
169: { mpfr_init_set_str(mp, s.c_str(), base); }
170: */
171:
172: explicit __gmp_expr(mpfr_srcptr f)
173: {
174: mpfr_init2(mp, mpfr_get_prec(f));
175: mpfr_set(mp, f, __gmp_default_rounding_mode);
176: }
177: explicit __gmp_expr(mpfr_srcptr f, unsigned long int prec)
178: {
179: mpfr_init2(mp, prec);
180: mpfr_set(mp, f, __gmp_default_rounding_mode);
181: }
182:
183: ~__gmp_expr() { mpfr_clear(mp); }
184:
185: // assignment operators
186: __gmp_expr & operator=(const __gmp_expr &f)
187: { mpfr_set(mp, f.mp, __gmp_default_rounding_mode); return *this; }
188: template <class T, class U>
189: __gmp_expr<__gmpfr_value, __gmpfr_value> & operator=
190: (const __gmp_expr<T, U> &expr)
191: { __gmp_set_expr(mp, expr); return *this; }
192:
193: __gmp_expr & operator=(signed char c)
194: { mpfr_set_si(mp, c, __gmp_default_rounding_mode); return *this; }
195: __gmp_expr & operator=(unsigned char c)
196: { mpfr_set_ui(mp, c, __gmp_default_rounding_mode); return *this; }
197:
198: __gmp_expr & operator=(signed int i)
199: { mpfr_set_si(mp, i, __gmp_default_rounding_mode); return *this; }
200: __gmp_expr & operator=(unsigned int i)
201: { mpfr_set_ui(mp, i, __gmp_default_rounding_mode); return *this; }
202:
203: __gmp_expr & operator=(signed short int s)
204: { mpfr_set_si(mp, s, __gmp_default_rounding_mode); return *this; }
205: __gmp_expr & operator=(unsigned short int s)
206: { mpfr_set_ui(mp, s, __gmp_default_rounding_mode); return *this; }
207:
208: __gmp_expr & operator=(signed long int l)
209: { mpfr_set_si(mp, l, __gmp_default_rounding_mode); return *this; }
210: __gmp_expr & operator=(unsigned long int l)
211: { mpfr_set_ui(mp, l, __gmp_default_rounding_mode); return *this; }
212:
213: __gmp_expr & operator=(float f)
214: { mpfr_set_d(mp, f, __gmp_default_rounding_mode); return *this; }
215: __gmp_expr & operator=(double d)
216: { mpfr_set_d(mp, d, __gmp_default_rounding_mode); return *this; }
217: /*
218: __gmp_expr & operator=(long double ld)
219: { mpfr_set_d(mp, ld, __gmp_default_rounding_mode); return *this; }
220: */
221:
222: /*
223: __gmp_expr & operator=(const char *s)
224: { mpfr_set_str(mp, s, mpfr_default_base); return *this; }
225: __gmp_expr & operator=(const std::string &s)
226: { mpfr_set_str(mp, s.c_str(), mpfr_default_base); return *this; }
227:
228: // string input/output functions
229: int set_str(const std::string &s, int base)
230: { return mpfr_set_str(mp, s.c_str(), base); }
231: */
232: std::string get_str(mp_exp_t *expo, int base, size_t size,
233: mp_rnd_t rmode = __gmp_default_rounding_mode) const
234: {
235: __gmp_alloc_cstring temp(mpfr_get_str(0, expo, base, size, mp, rmode));
236: return std::string(temp.str);
237: }
238:
239: // conversion functions
240: mpfr_srcptr get_mpfr_t() const { return mp; }
241: mpfr_ptr get_mpfr_t() { return mp; }
242:
243: // signed long get_si() const { return mpfr_get_si(mp); }
244: // unsigned long get_ui() const { return mpfr_get_ui(mp); }
245: double get_d() const // should be long double
246: { return mpfr_get_d(mp, __gmp_default_rounding_mode); }
247:
248: // compound assignments
249: __GMPFR_DECLARE_COMPOUND_OPERATOR(operator+=)
250: __GMPFR_DECLARE_COMPOUND_OPERATOR(operator-=)
251: __GMPFR_DECLARE_COMPOUND_OPERATOR(operator*=)
252: __GMPFR_DECLARE_COMPOUND_OPERATOR(operator/=)
253:
254: __GMPFR_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
255: __GMPFR_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
256:
257: __GMPFR_DECLARE_INCREMENT_OPERATOR(operator++)
258: __GMPFR_DECLARE_INCREMENT_OPERATOR(operator--)
259: };
260:
261: typedef __gmp_expr<__gmpfr_value, __gmpfr_value> mpfr_class;
262:
263:
264: inline std::ostream & operator<<(std::ostream &o, const mpfr_class &f)
265: {
266: mp_exp_t expo;
267: int base = 10;
268: __gmp_alloc_cstring temp(mpfr_get_str(0, &expo, base, 0, f.get_mpfr_t(),
269: __gmp_default_rounding_mode));
270:
271: // cancel terminating zeros
272: for (size_t i=strlen(temp.str)-1; temp.str[i]=='0' && i>0; --i)
273: temp.str[i] = '\0';
274:
275: if (*temp.str == '-')
276: o << "-0." << temp.str+1;
277: else
278: o << "0." << temp.str;
279:
280: if (base <= 10)
281: o << "e" << expo;
282: else
283: o << "@" << expo;
284:
285: return o;
286: }
287:
288: template <class T>
289: inline std::ostream & operator<<
290: (std::ostream &o, const __gmp_expr<__gmpfr_value, T> &expr)
291: {
292: mpfr_class temp(expr);
293: return o << temp;
294: }
295:
296: inline std::istream & operator>>(std::istream &i, mpfr_class &f)
297: {
298: mpf_t temp;
299: mpf_init2(temp, f.get_prec());
300: i >> temp;
301: mpfr_set_f(f.get_mpfr_t(), temp, __gmp_default_rounding_mode);
302: mpf_clear(temp);
303: return i;
304: }
305:
306:
307: /**************** Classes for type conversion ****************/
308:
309: class __gmpfr_temp
310: {
311: private:
312: mpfr_srcptr mp;
313: bool is_temp;
314: mpfr_t temp;
315:
316: __gmpfr_temp();
317: __gmpfr_temp(const __gmpfr_temp &);
318: void operator=(const __gmpfr_temp &);
319: public:
320: __gmpfr_temp(const mpfr_class &f) : mp(f.get_mpfr_t()), is_temp(false) { }
321: __gmpfr_temp(const mpfr_class &f, unsigned long int)
322: : mp(f.get_mpfr_t()), is_temp(false) { }
323: template <class T, class U>
324: __gmpfr_temp(const __gmp_expr<T, U> &expr)
325: {
326: mpfr_init2(temp, expr.get_prec());
327: __gmp_set_expr(temp, expr);
328: mp = temp;
329: is_temp = true;
330: }
331: template <class T, class U>
332: __gmpfr_temp(const __gmp_expr<T, U> &expr, unsigned long int prec)
333: {
334: mpfr_init2(temp, prec);
335: __gmp_set_expr(temp, expr);
336: mp = temp;
337: is_temp = true;
338: }
339: ~__gmpfr_temp() { if (is_temp) mpfr_clear(temp); }
340:
341: mpfr_srcptr get_mp() const { return mp; }
342: };
343:
344:
345: template <>
346: struct __gmp_resolve_expr<__gmpz_value, __gmpfr_value>
347: {
348: typedef __gmpfr_value value_type;
349: typedef __gmpfr_temp temp_type;
350: };
351:
352: template <>
353: struct __gmp_resolve_expr<__gmpfr_value, __gmpz_value>
354: {
355: typedef __gmpfr_value value_type;
356: typedef __gmpfr_temp temp_type;
357: };
358:
359: template <>
360: struct __gmp_resolve_expr<__gmpq_value, __gmpfr_value>
361: {
362: typedef __gmpfr_value value_type;
363: typedef __gmpfr_temp temp_type;
364: };
365:
366: template <>
367: struct __gmp_resolve_expr<__gmpfr_value, __gmpq_value>
368: {
369: typedef __gmpfr_value value_type;
370: typedef __gmpfr_temp temp_type;
371: };
372:
373: template <>
374: struct __gmp_resolve_expr<__gmpf_value, __gmpfr_value>
375: {
376: typedef __gmpfr_value value_type;
377: typedef __gmpfr_temp temp_type;
378: };
379:
380: template <>
381: struct __gmp_resolve_expr<__gmpfr_value, __gmpf_value>
382: {
383: typedef __gmpfr_value value_type;
384: typedef __gmpfr_temp temp_type;
385: };
386:
387: template <>
388: struct __gmp_resolve_expr<__gmpfr_value, __gmpfr_value>
389: {
390: typedef __gmpfr_value value_type;
391: typedef __gmpfr_temp temp_type;
392: };
393:
394:
395: /*
396: template <class T>
397: inline void __gmp_set_expr(mpz_ptr z, const mpfr_class &f)
398: {
399: mpz_set_fr(z, f.get_mpfr_t());
400: }
401:
402: template <class T>
403: inline void __gmp_set_expr
404: (mpz_ptr z, const __gmp_expr<__gmpfr_value, T> &expr)
405: {
406: mpfr_class temp(expr);
407: mpz_set_fr(z, temp.get_mpfr_t());
408: }
409:
410: template <class T>
411: inline void __gmp_set_expr(mpq_ptr q, const mpfr_class &f)
412: {
413: mpq_set_fr(q, f.get_mpfr_t());
414: }
415:
416: template <class T>
417: inline void __gmp_set_expr
418: (mpq_ptr q, const __gmp_expr<__gmpfr_value, T> &expr)
419: {
420: mpfr_class temp(expr);
421: mpq_set_fr(q, temp.get_mpfr_t());
422: }
423:
424: template <class T>
425: inline void __gmp_set_expr(mpf_ptr f, const mpfr_class &g)
426: {
427: mpf_set_fr(f, g.get_mpfr_t());
428: }
429:
430: template <class T>
431: inline void __gmp_set_expr
432: (mpf_ptr f, const __gmp_expr<__gmpfr_value, T> &expr)
433: {
434: mpfr_class temp(expr);
435: mpf_set_fr(f, temp.get_mpfr_t());
436: }
437: */
438:
439: template <class T>
440: inline void __gmp_set_expr(mpfr_ptr f, const mpz_class &z)
441: {
442: mpfr_set_z(f, z.get_mpz_t(), __gmp_default_rounding_mode);
443: }
444:
445: template <class T>
446: inline void __gmp_set_expr(mpfr_ptr f, const mpz_classref &z)
447: {
448: mpfr_set_z(f, z.get_mpz_t(), __gmp_default_rounding_mode);
449: }
450:
451: template <class T>
452: inline void __gmp_set_expr
453: (mpfr_ptr f, const __gmp_expr<__gmpz_value, T> &expr)
454: {
455: mpz_class temp(expr);
456: mpfr_set_z(f, temp.get_mpz_t(), __gmp_default_rounding_mode);
457: }
458:
459: template <class T>
460: inline void __gmp_set_expr(mpfr_ptr f, const mpq_class &q)
461: {
462: mpfr_set_q(f, q.get_mpq_t(), __gmp_default_rounding_mode);
463: }
464:
465: template <class T>
466: inline void __gmp_set_expr
467: (mpfr_ptr f, const __gmp_expr<__gmpq_value, T> &expr)
468: {
469: mpq_class temp(expr);
470: mpfr_set_q(f, temp.get_mpq_t(), __gmp_default_rounding_mode);
471: }
472:
473: template <class T>
474: inline void __gmp_set_expr(mpfr_ptr f, const mpf_class &g)
475: {
476: mpfr_set_f(f, g.get_mpf_t(), __gmp_default_rounding_mode);
477: }
478:
479: template <class T>
480: inline void __gmp_set_expr
481: (mpfr_ptr f, const __gmp_expr<__gmpf_value, T> &expr)
482: {
483: mpq_class temp(expr);
484: mpfr_set_f(f, temp.get_mpf_t(), __gmp_default_rounding_mode);
485: }
486:
487: template <>
488: inline void __gmp_set_expr(mpfr_ptr f, const mpfr_class &g)
489: {
490: mpfr_set(f, g.get_mpfr_t(), __gmp_default_rounding_mode);
491: }
492:
493: template <class T>
494: inline void __gmp_set_expr
495: (mpfr_ptr f, const __gmp_expr<__gmpfr_value, T> &expr)
496: {
497: expr.eval(f, mpfr_get_prec(f));
498: }
499:
500:
501: /**************** Specializations of __gmp_expr ****************/
502:
503: // unary expressions
504:
505: template <class Op>
506: class __gmp_expr<__gmpfr_value, __gmp_unary_expr<mpfr_class, Op> >
507: {
508: private:
509: __gmp_unary_expr<mpfr_class, Op> expr;
510: public:
511: __gmp_expr(const mpfr_class &val) : expr(val) { }
512: void eval(mpfr_ptr f, unsigned long int) const
513: { Op::eval(f, expr.val.get_mpfr_t(), __gmp_default_rounding_mode); }
514: unsigned long int get_prec() const
515: { return mpfr_get_prec(expr.val.get_mpfr_t()); }
516: };
517:
518: template <class T, class U, class Op>
519: class __gmp_expr<__gmpfr_value, __gmp_unary_expr<__gmp_expr<T, U>, Op> >
520: {
521: private:
522: __gmp_unary_expr<__gmp_expr<T, U>, Op> expr;
523: public:
524: __gmp_expr(const __gmp_expr<T, U> &val) : expr(val) { }
525: void eval(mpfr_ptr f, unsigned long int prec) const
526: {
527: mpfr_class temp(expr.val, prec);
528: Op::eval(f, temp.get_mpfr_t(), __gmp_default_rounding_mode);
529: }
530: unsigned long int get_prec() const { return expr.val.get_prec(); }
531: };
532:
533:
534: // binary expressions
535:
536: template <class Op>
537: class __gmp_expr
538: <__gmpfr_value, __gmp_binary_expr<mpfr_class, mpfr_class, Op> >
539: {
540: private:
541: __gmp_binary_expr<mpfr_class, mpfr_class, Op> expr;
542: public:
543: __gmp_expr(const mpfr_class &val1, const mpfr_class &val2)
544: : expr(val1, val2) { }
545: void eval(mpfr_ptr f, unsigned long int) const
546: { Op::eval(f, expr.val1.get_mpfr_t(), expr.val2.get_mpfr_t(),
547: __gmp_default_rounding_mode); }
548: unsigned long int get_prec() const
549: {
550: unsigned long int prec1 = expr.val1.get_prec(),
551: prec2 = expr.val2.get_prec();
552: return (prec1 > prec2) ? prec1 : prec2;
553: }
554: };
555:
556: template <class T, class Op>
557: class __gmp_expr<__gmpfr_value, __gmp_binary_expr<mpfr_class, T, Op> >
558: {
559: private:
560: __gmp_binary_expr<mpfr_class, T, Op> expr;
561: public:
562: __gmp_expr(const mpfr_class &val1, T val2) : expr(val1, val2) { }
563: void eval(mpfr_ptr f, unsigned long int) const
564: { Op::eval(f, expr.val1.get_mpfr_t(), expr.val2,
565: __gmp_default_rounding_mode); }
566: unsigned long int get_prec() const
567: {
568: unsigned long int prec1 = expr.val1.get_prec(),
569: prec2 = mpf_get_default_prec();
570: return (prec1 > prec2) ? prec1 : prec2;
571: }
572: };
573:
574: template <class T, class Op>
575: class __gmp_expr<__gmpfr_value, __gmp_binary_expr<T, mpfr_class, Op> >
576: {
577: private:
578: __gmp_binary_expr<T, mpfr_class, Op> expr;
579: public:
580: __gmp_expr(T val1, const mpfr_class &val2) : expr(val1, val2) { }
581: void eval(mpfr_ptr f, unsigned long int) const
582: { Op::eval(f, expr.val1, expr.val2.get_mpfr_t(),
583: __gmp_default_rounding_mode); }
584: unsigned long int get_prec() const
585: {
586: unsigned long int prec1 = mpf_get_default_prec(),
587: prec2 = expr.val2.get_prec();
588: return (prec1 > prec2) ? prec1 : prec2;
589: }
590: };
591:
592: template <class T, class U, class Op>
593: class __gmp_expr
594: <__gmpfr_value, __gmp_binary_expr<mpfr_class, __gmp_expr<T, U>, Op> >
595: {
596: private:
597: __gmp_binary_expr<mpfr_class, __gmp_expr<T, U>, Op> expr;
598: public:
599: __gmp_expr(const mpfr_class &val1, const __gmp_expr<T, U> &val2)
600: : expr(val1, val2) { }
601: void eval(mpfr_ptr f, unsigned long int prec) const
602: {
603: mpfr_class temp(expr.val2, prec);
604: Op::eval(f, expr.val1.get_mpfr_t(), temp.get_mpfr_t(),
605: __gmp_default_rounding_mode);
606: }
607: unsigned long int get_prec() const
608: {
609: unsigned long int prec1 = expr.val1.get_prec(),
610: prec2 = expr.val2.get_prec();
611: return (prec1 > prec2) ? prec1 : prec2;
612: }
613: };
614:
615: template <class T, class U, class Op>
616: class __gmp_expr
617: <__gmpfr_value, __gmp_binary_expr<__gmp_expr<T, U>, mpfr_class, Op> >
618: {
619: private:
620: __gmp_binary_expr<__gmp_expr<T, U>, mpfr_class, Op> expr;
621: public:
622: __gmp_expr(const __gmp_expr<T, U> &val1, const mpfr_class &val2)
623: : expr(val1, val2) { }
624: void eval(mpfr_ptr f, unsigned long int prec) const
625: {
626: mpfr_class temp(expr.val1, prec);
627: Op::eval(f, temp.get_mpfr_t(), expr.val2.get_mpfr_t(),
628: __gmp_default_rounding_mode);
629: }
630: unsigned long int get_prec() const
631: {
632: unsigned long int prec1 = expr.val1.get_prec(),
633: prec2 = expr.val2.get_prec();
634: return (prec1 > prec2) ? prec1 : prec2;
635: }
636: };
637:
638: template <class T, class U, class V, class Op>
639: class __gmp_expr<__gmpfr_value, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> >
640: {
641: private:
642: __gmp_binary_expr<__gmp_expr<T, U>, V, Op> expr;
643: public:
644: __gmp_expr(const __gmp_expr<T, U> &val1, V val2) : expr(val1, val2) { }
645: void eval(mpfr_ptr f, unsigned long int prec) const
646: {
647: mpfr_class temp(expr.val1, prec);
648: Op::eval(f, temp.get_mpfr_t(), expr.val2, __gmp_default_rounding_mode);
649: }
650: unsigned long int get_prec() const
651: {
652: unsigned long int prec1 = expr.val1.get_prec(),
653: prec2 = mpf_get_default_prec();
654: return (prec1 > prec2) ? prec1 : prec2;
655: }
656: };
657:
658: template <class T, class U, class V, class Op>
659: class __gmp_expr<__gmpfr_value, __gmp_binary_expr<T, __gmp_expr<U, V>, Op> >
660: {
661: private:
662: __gmp_binary_expr<T, __gmp_expr<U, V>, Op> expr;
663: public:
664: __gmp_expr(T val1, const __gmp_expr<U, V> &val2) : expr(val1, val2) { }
665: void eval(mpfr_ptr f, unsigned long int prec) const
666: {
667: mpfr_class temp(expr.val2, prec);
668: Op::eval(f, expr.val1, temp.get_mpfr_t(), __gmp_default_rounding_mode);
669: }
670: unsigned long int get_prec() const
671: {
672: unsigned long int prec1 = mpf_get_default_prec(),
673: prec2 = expr.val2.get_prec();
674: return (prec1 > prec2) ? prec1 : prec2;
675: }
676: };
677:
678: template <class T, class U, class V, class W, class Op>
679: class __gmp_expr
680: <__gmpfr_value, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
681: {
682: private:
683: __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> expr;
684: public:
685: __gmp_expr(const __gmp_expr<T, U> &val1, const __gmp_expr<V, W> &val2)
686: : expr(val1, val2) { }
687: void eval(mpfr_ptr f, unsigned long int prec) const
688: {
689: mpfr_class temp1(expr.val1, prec), temp2(expr.val2, prec);
690: Op::eval(f, temp1.get_mpfr_t(), temp2.get_mpfr_t(),
691: __gmp_default_rounding_mode);
692: }
693: unsigned long int get_prec() const
694: {
695: unsigned long int prec1 = expr.val1.get_prec(),
696: prec2 = expr.val2.get_prec();
697: return (prec1 > prec2) ? prec1 : prec2;
698: }
699: };
700:
701:
702: /**************** Macros for defining functions ****************/
703:
704: #define __GMPFRR_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
705: \
706: template <class T, class U> \
707: inline mpfr_class & mpfr_class::fun(const __gmp_expr<T, U> &expr) \
708: { \
709: __gmpfr_temp temp(expr, get_prec()); \
710: eval_fun::eval(mp, mp, temp.get_mp(), __gmp_default_rounding_mode); \
711: return *this; \
712: }
713:
714: #define __GMPFRN_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
715: \
716: inline mpfr_class & mpfr_class::fun(signed char c) \
717: { \
718: eval_fun::eval(mp, mp, (signed long int) c, \
719: __gmp_default_rounding_mode); \
720: return *this; \
721: } \
722: \
723: inline mpfr_class & mpfr_class::fun(unsigned char c) \
724: { \
725: eval_fun::eval(mp, mp, (unsigned long int) c, \
726: __gmp_default_rounding_mode); \
727: return *this; \
728: } \
729: \
730: inline mpfr_class & mpfr_class::fun(signed int i) \
731: { \
732: eval_fun::eval(mp, mp, (signed long int) i, \
733: __gmp_default_rounding_mode); \
734: return *this; \
735: } \
736: \
737: inline mpfr_class & mpfr_class::fun(unsigned int i) \
738: { \
739: eval_fun::eval(mp, mp, (unsigned long int) i, \
740: __gmp_default_rounding_mode); \
741: return *this; \
742: } \
743: \
744: inline mpfr_class & mpfr_class::fun(signed short int s) \
745: { \
746: eval_fun::eval(mp, mp, (signed long int) s, \
747: __gmp_default_rounding_mode); \
748: return *this; \
749: } \
750: \
751: inline mpfr_class & mpfr_class::fun(unsigned short int s) \
752: { \
753: eval_fun::eval(mp, mp, (unsigned long int) s, \
754: __gmp_default_rounding_mode); \
755: return *this; \
756: } \
757: \
758: inline mpfr_class & mpfr_class::fun(signed long int l) \
759: { \
760: eval_fun::eval(mp, mp, l, __gmp_default_rounding_mode); \
761: return *this; \
762: } \
763: \
764: inline mpfr_class & mpfr_class::fun(unsigned long int l) \
765: { \
766: eval_fun::eval(mp, mp, l, __gmp_default_rounding_mode); \
767: return *this; \
768: } \
769: \
770: inline mpfr_class & mpfr_class::fun(float f) \
771: { \
772: eval_fun::eval(mp, mp, (double) f, __gmp_default_rounding_mode); \
773: return *this; \
774: } \
775: \
776: inline mpfr_class & mpfr_class::fun(double d) \
777: { \
778: eval_fun::eval(mp, mp, d, __gmp_default_rounding_mode); \
779: return *this; \
780: } \
781: \
782: /* \
783: inline mpfr_class & mpfr_class::fun(long double ld) \
784: { \
785: eval_fun::eval(mp, mp, ld, __gmp_default_rounding_mode); \
786: return *this; \
787: } */
788:
789: #define __GMPFR_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
790: __GMPFRR_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
791: __GMPFRN_DEFINE_COMPOUND_OPERATOR(fun, eval_fun)
792:
793: #define __GMPFR_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
794: \
795: inline mpfr_class & mpfr_class::fun(unsigned long int l) \
796: { \
797: eval_fun::eval(mp, mp, l, __gmp_default_rounding_mode); \
798: return *this; \
799: }
800:
801: #define __GMPFR_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
802: \
803: inline mpfr_class & mpfr_class::fun() \
804: { \
805: eval_fun::eval(mp, mp, __gmp_default_rounding_mode); \
806: return *this; \
807: } \
808: \
809: inline mpfr_class mpfr_class::fun(int) \
810: { \
811: mpfr_class temp(*this); \
812: eval_fun::eval(mp, mp, __gmp_default_rounding_mode); \
813: return temp; \
814: }
815:
816:
817: /**************** Arithmetic operators and functions ****************/
818:
819: __GMPFR_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
820: __GMPFR_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
821: __GMPFR_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
822: __GMPFR_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
823:
824: __GMPFR_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
825: __GMPFR_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
826:
827: __GMPFR_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
828: __GMPFR_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
829:
830:
831: /**************** #undef all private macros ****************/
832:
833: #undef __GMPFRR_DECLARE_COMPOUND_OPERATOR
834: #undef __GMPFRN_DECLARE_COMPOUND_OPERATOR
835: #undef __GMPFR_DECLARE_COMPOUND_OPERATOR
836: #undef __GMPFR_DECLARE_COMPOUND_OPERATOR_UI
837: #undef __GMPFR_DECLARE_INCREMENT_OPERATOR
838:
839: #undef __GMPFRR_DEFINE_COMPOUND_OPERATOR
840: #undef __GMPFRN_DEFINE_COMPOUND_OPERATOR
841: #undef __GMPFR_DEFINE_COMPOUND_OPERATOR
842: #undef __GMPFR_DEFINE_COMPOUND_OPERATOR_UI
843: #undef __GMPFR_DEFINE_INCREMENT_OPERATOR
844:
845:
846: #endif /* __GMPFR_PLUSPLUS__ */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>