source: trunk/third/gmp/mpfrxx.h @ 22254

Revision 22254, 28.4 KB checked in by ghudson, 19 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r22253, which included commits to RCS files with non-trunk default branches.
Line 
1/* mpfrxx.h -- C++ class wrapper for MPFR.  -*- C++ -*-
2
3Copyright 2001, 2002, 2004 Free Software Foundation, Inc.
4
5This file is part of the GNU MP Library.
6
7The GNU MP Library is free software; you can redistribute it and/or modify
8it under the terms of the GNU Lesser General Public License as published by
9the Free Software Foundation; either version 2.1 of the License, or (at your
10option) any later version.
11
12The GNU MP Library is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15License for more details.
16
17You should have received a copy of the GNU Lesser General Public License
18along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
19the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20MA 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
32class __gmpfr_value { };
33
34template <class T, class U>
35void __gmp_set_expr(mpfr_ptr, const __gmp_expr<T, U> &);
36
37const 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
73template <>
74class __gmp_expr<__gmpfr_value, __gmpfr_value>
75{
76private:
77  mpfr_t mp;
78public:
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
261typedef __gmp_expr<__gmpfr_value, __gmpfr_value> mpfr_class;
262
263
264inline 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
288template <class T>
289inline 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
296inline 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
309class __gmpfr_temp
310{
311private:
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 &);
319public:
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
345template <>
346struct __gmp_resolve_expr<__gmpz_value, __gmpfr_value>
347{
348  typedef __gmpfr_value value_type;
349  typedef __gmpfr_temp temp_type;
350};
351
352template <>
353struct __gmp_resolve_expr<__gmpfr_value, __gmpz_value>
354{
355  typedef __gmpfr_value value_type;
356  typedef __gmpfr_temp temp_type;
357};
358
359template <>
360struct __gmp_resolve_expr<__gmpq_value, __gmpfr_value>
361{
362  typedef __gmpfr_value value_type;
363  typedef __gmpfr_temp temp_type;
364};
365
366template <>
367struct __gmp_resolve_expr<__gmpfr_value, __gmpq_value>
368{
369  typedef __gmpfr_value value_type;
370  typedef __gmpfr_temp temp_type;
371};
372
373template <>
374struct __gmp_resolve_expr<__gmpf_value, __gmpfr_value>
375{
376  typedef __gmpfr_value value_type;
377  typedef __gmpfr_temp temp_type;
378};
379
380template <>
381struct __gmp_resolve_expr<__gmpfr_value, __gmpf_value>
382{
383  typedef __gmpfr_value value_type;
384  typedef __gmpfr_temp temp_type;
385};
386
387template <>
388struct __gmp_resolve_expr<__gmpfr_value, __gmpfr_value>
389{
390  typedef __gmpfr_value value_type;
391  typedef __gmpfr_temp temp_type;
392};
393
394
395/*
396template <class T>
397inline void __gmp_set_expr(mpz_ptr z, const mpfr_class &f)
398{
399  mpz_set_fr(z, f.get_mpfr_t());
400}
401
402template <class T>
403inline 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
410template <class T>
411inline void __gmp_set_expr(mpq_ptr q, const mpfr_class &f)
412{
413  mpq_set_fr(q, f.get_mpfr_t());
414}
415
416template <class T>
417inline 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
424template <class T>
425inline void __gmp_set_expr(mpf_ptr f, const mpfr_class &g)
426{
427  mpf_set_fr(f, g.get_mpfr_t());
428}
429
430template <class T>
431inline 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
439template <class T>
440inline 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
445template <class T>
446inline 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
451template <class T>
452inline 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
459template <class T>
460inline 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
465template <class T>
466inline 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
473template <class T>
474inline 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
479template <class T>
480inline void __gmp_set_expr
481(mpfr_ptr f, const __gmp_expr<__gmpf_value, T> &expr)
482{
483  mpf_class temp(expr);
484  mpfr_set_f(f, temp.get_mpf_t(), __gmp_default_rounding_mode);
485}
486
487template <>
488inline 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
493template <class T>
494inline 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
505template <class Op>
506class __gmp_expr<__gmpfr_value, __gmp_unary_expr<mpfr_class, Op> >
507{
508private:
509  __gmp_unary_expr<mpfr_class, Op> expr;
510public:
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
518template <class T, class U, class Op>
519class __gmp_expr<__gmpfr_value, __gmp_unary_expr<__gmp_expr<T, U>, Op> >
520{
521private:
522  __gmp_unary_expr<__gmp_expr<T, U>, Op> expr;
523public:
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
536template <class Op>
537class __gmp_expr
538<__gmpfr_value, __gmp_binary_expr<mpfr_class, mpfr_class, Op> >
539{
540private:
541  __gmp_binary_expr<mpfr_class, mpfr_class, Op> expr;
542public:
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
556template <class T, class Op>
557class __gmp_expr<__gmpfr_value, __gmp_binary_expr<mpfr_class, T, Op> >
558{
559private:
560  __gmp_binary_expr<mpfr_class, T, Op> expr;
561public:
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
574template <class T, class Op>
575class __gmp_expr<__gmpfr_value, __gmp_binary_expr<T, mpfr_class, Op> >
576{
577private:
578  __gmp_binary_expr<T, mpfr_class, Op> expr;
579public:
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
592template <class T, class U, class Op>
593class __gmp_expr
594<__gmpfr_value, __gmp_binary_expr<mpfr_class, __gmp_expr<T, U>, Op> >
595{
596private:
597  __gmp_binary_expr<mpfr_class, __gmp_expr<T, U>, Op> expr;
598public:
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
615template <class T, class U, class Op>
616class __gmp_expr
617<__gmpfr_value, __gmp_binary_expr<__gmp_expr<T, U>, mpfr_class, Op> >
618{
619private:
620  __gmp_binary_expr<__gmp_expr<T, U>, mpfr_class, Op> expr;
621public:
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
638template <class T, class U, class V, class Op>
639class __gmp_expr<__gmpfr_value, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> >
640{
641private:
642  __gmp_binary_expr<__gmp_expr<T, U>, V, Op> expr;
643public:
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
658template <class T, class U, class V, class Op>
659class __gmp_expr<__gmpfr_value, __gmp_binary_expr<T, __gmp_expr<U, V>, Op> >
660{
661private:
662  __gmp_binary_expr<T, __gmp_expr<U, V>, Op> expr;
663public:
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
678template <class T, class U, class V, class W, class Op>
679class __gmp_expr
680<__gmpfr_value, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
681{
682private:
683  __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> expr;
684public:
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                                                                      \
706template <class T, class U>                                           \
707inline 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                                                                   \
716inline 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                                                                   \
723inline 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                                                                   \
730inline 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                                                                   \
737inline 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                                                                   \
744inline 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                                                                   \
751inline 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                                                                   \
758inline 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                                                                   \
764inline 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                                                                   \
770inline 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                                                                   \
776inline 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/*                                                                 \
783inline 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                                                           \
795inline 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                                                         \
803inline mpfr_class & mpfr_class::fun()                    \
804{                                                        \
805  eval_fun::eval(mp, mp, __gmp_default_rounding_mode);   \
806  return *this;                                          \
807}                                                        \
808                                                         \
809inline 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__ */
Note: See TracBrowser for help on using the repository browser.