plll  1.0
arithmetic-gmp-conv.hpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 2011-2014 University of Zurich
3 
4  Permission is hereby granted, free of charge, to any person obtaining a copy
5  of this software and associated documentation files (the "Software"), to deal
6  in the Software without restriction, including without limitation the rights
7  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  copies of the Software, and to permit persons to whom the Software is
9  furnished to do so, subject to the following conditions:
10 
11  The above copyright notice and this permission notice shall be included in
12  all copies or substantial portions of the Software.
13 
14  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  THE SOFTWARE.
21 */
22 
23 #ifndef PLLL_INCLUDE_GUARD__ARITHMETIC_GMP_CONVERSIONS_HPP
24 #define PLLL_INCLUDE_GUARD__ARITHMETIC_GMP_CONVERSIONS_HPP
25 
33 namespace plll
34 {
35  namespace arithmetic
36  {
37  namespace implementation
38  {
39  // Implementation for IntegerContext
40 
41  template<class Data, template<typename, typename> class Op, class Dest>
42  class conversion_impl<expressions::Expression<IntegerContext, Data, Op>, Dest>
43  {
44  public:
45  typedef typename conversion_impl<Integer, Dest>::RetVal RetVal;
46  typedef void RetVal_Frac;
47  typedef void RetVal_Floor;
48  typedef void RetVal_Ceil;
49  typedef void RetVal_Round;
50  typedef void RetVal_Round2;
51 
52  static void convert(typename Dest::Type & d, const expressions::Expression<IntegerContext, Data, Op> & v, const Dest & c)
53  {
54  conversion_impl<Integer, Dest>::convert(d, static_cast<Integer>(v), c);
55  }
56 
57  static RetVal convert(const expressions::Expression<IntegerContext, Data, Op> & v, const Dest & c)
58  {
59  return conversion_impl<Integer, Dest>::convert(static_cast<Integer>(v), c);
60  }
61  };
62 
63  template<> class conversion_impl<signed long, IntegerContext>
64  {
65  public:
67  typedef void RetVal_Frac;
68  typedef void RetVal_Floor;
69  typedef void RetVal_Ceil;
70  typedef void RetVal_Round;
71  typedef void RetVal_Round2;
72 
73  static void convert(Integer & d, const signed long & v, const IntegerContext & c)
74  {
75  mpz_set_si(d.d_value, v);
76  }
77 
78  static RetVal convert(const signed long & v, const IntegerContext & c)
79  {
80  return RetVal(v, c);
81  }
82  };
83 
84  template<> class conversion_impl<unsigned long, IntegerContext>
85  {
86  public:
88  typedef void RetVal_Frac;
89  typedef void RetVal_Floor;
90  typedef void RetVal_Ceil;
91  typedef void RetVal_Round;
92  typedef void RetVal_Round2;
93 
94  static void convert(Integer & d, const unsigned long & v, const IntegerContext & c)
95  {
96  mpz_set_ui(d.d_value, v);
97  }
98 
99  static RetVal convert(const unsigned long & v, const IntegerContext & c)
100  {
101  return RetVal(v, c);
102  }
103  };
104 
105  template<> class conversion_impl<signed int, IntegerContext>
106  {
107  public:
109  typedef void RetVal_Frac;
110  typedef void RetVal_Floor;
111  typedef void RetVal_Ceil;
112  typedef void RetVal_Round;
113  typedef void RetVal_Round2;
114 
115  static void convert(Integer & d, const signed int & v, const IntegerContext & c)
116  {
117  mpz_set_si(d.d_value, v);
118  }
119 
120  static RetVal convert(const signed int & v, const IntegerContext & c)
121  {
122  return RetVal(v, c);
123  }
124  };
125 
126  template<> class conversion_impl<unsigned int, IntegerContext>
127  {
128  public:
130  typedef void RetVal_Frac;
131  typedef void RetVal_Floor;
132  typedef void RetVal_Ceil;
133  typedef void RetVal_Round;
134  typedef void RetVal_Round2;
135 
136  static void convert(Integer & d, const unsigned int & v, const IntegerContext & c)
137  {
138  mpz_set_ui(d.d_value, v);
139  }
140 
141  static RetVal convert(const unsigned int & v, const IntegerContext & c)
142  {
143  return RetVal(v, c);
144  }
145  };
146 
147  template<> class conversion_impl<long long, IntegerContext>
148  {
149  public:
151  typedef void RetVal_Frac;
152  typedef void RetVal_Floor;
153  typedef void RetVal_Ceil;
154  typedef void RetVal_Round;
155  typedef void RetVal_Round2;
156 
157  static void convert(Integer & d, const long long & v, const IntegerContext & c)
158  {
159  Integer::mpz_set_ll(d.d_value, v);
160  }
161 
162  static RetVal convert(const long long & v, const IntegerContext & c)
163  {
164  return RetVal(v, c);
165  }
166  };
167 
168  template<> class conversion_impl<float, IntegerContext>
169  {
170  public:
172  typedef void RetVal_Frac;
177 
178  static void convert(Integer & d, const float & v, const IntegerContext & c)
179  {
180  mpz_set_d(d.d_value, v);
181  }
182 
183  static RetVal convert(const float & v, const IntegerContext & c)
184  {
185  return RetVal(v, c);
186  }
187 
188  static void floor(Integer & d, const float & v, const IntegerContext & c)
189  {
190  mpz_set_d(d.d_value, std::floor(v));
191  }
192 
193  static RetVal floor(const float & v, const IntegerContext & c)
194  {
195  return RetVal(std::floor(v), c);
196  }
197 
198  static void round(Integer & d, const float & v, const IntegerContext & c)
199  {
200  mpz_set_d(d.d_value, rintf(v));
201  }
202 
203  static RetVal round(const float & v, const IntegerContext & c)
204  {
205  return RetVal(rintf(v), c);
206  }
207 
208  static void round(Integer & d, const float & v, bool & roundUp, const IntegerContext & c)
209  {
210  float rv = rintf(v);
211  roundUp = rv > v;
212  mpz_set_d(d.d_value, rv);
213  }
214 
215  static RetVal round(const float & v, bool & roundUp, const IntegerContext & c)
216  {
217  float rv = rintf(v);
218  roundUp = rv > v;
219  return RetVal(rv, c);
220  }
221 
222  static void ceil(Integer & d, const float & v, const IntegerContext & c)
223  {
224  mpz_set_d(d.d_value, std::ceil(v));
225  }
226 
227  static RetVal ceil(const float & v, const IntegerContext & c)
228  {
229  return RetVal(std::ceil(v), c);
230  }
231  };
232 
233  template<> class conversion_impl<double, IntegerContext>
234  {
235  public:
237  typedef void RetVal_Frac;
242 
243  static void convert(Integer & d, const double & v, const IntegerContext & c)
244  {
245  mpz_set_d(d.d_value, v);
246  }
247 
248  static RetVal convert(const double & v, const IntegerContext & c)
249  {
250  return RetVal(v, c);
251  }
252 
253  static void floor(Integer & d, const double & v, const IntegerContext & c)
254  {
255  mpz_set_d(d.d_value, std::floor(v));
256  }
257 
258  static RetVal floor(const double & v, const IntegerContext & c)
259  {
260  return RetVal(std::floor(v), c);
261  }
262 
263  static void round(Integer & d, const double & v, const IntegerContext & c)
264  {
265  mpz_set_d(d.d_value, rint(v));
266  }
267 
268  static RetVal round(const double & v, const IntegerContext & c)
269  {
270  return RetVal(rint(v), c);
271  }
272 
273  static void round(Integer & d, const double & v, bool & roundUp, const IntegerContext & c)
274  {
275  double rv = rint(v);
276  roundUp = rv > v;
277  mpz_set_d(d.d_value, rv);
278  }
279 
280  static RetVal round(const double & v, bool & roundUp, const IntegerContext & c)
281  {
282  double rv = rint(v);
283  roundUp = rv > v;
284  return RetVal(rv, c);
285  }
286 
287  static void ceil(Integer & d, const double & v, const IntegerContext & c)
288  {
289  mpz_set_d(d.d_value, std::ceil(v));
290  }
291 
292  static RetVal ceil(const double & v, const IntegerContext & c)
293  {
294  return RetVal(v, c);
295  }
296  };
297 
298  template<> class conversion_impl<long double, IntegerContext>
299  {
300  public:
302  typedef void RetVal_Frac;
307 
308  static void convert(Integer & d, const long double & v, const IntegerContext & c)
309  {
310  Integer::mpz_set_ld(d.d_value, v);
311  }
312 
313  static RetVal convert(const long double & v, const IntegerContext & c)
314  {
315  return RetVal(v, c);
316  }
317 
318  static void floor(Integer & d, const long double & v, const IntegerContext & c)
319  {
320  Integer::mpz_set_ld(d.d_value, std::floor(v));
321  }
322 
323  static RetVal floor(const long double & v, const IntegerContext & c)
324  {
325  return RetVal(v, c);
326  }
327 
328  static void round(Integer & d, const long double & v, const IntegerContext & c)
329  {
330  Integer::mpz_set_ld(d.d_value, rintl(v));
331  }
332 
333  static RetVal round(const long double & v, const IntegerContext & c)
334  {
335  return RetVal(rintl(v), c);
336  }
337 
338  static void round(Integer & d, const long double & v, bool & roundUp, const IntegerContext & c)
339  {
340  long double rv = rintl(v);
341  roundUp = rv > v;
342  Integer::mpz_set_ld(d.d_value, rv);
343  }
344 
345  static RetVal round(const long double & v, bool & roundUp, const IntegerContext & c)
346  {
347  long double rv = rintl(v);
348  roundUp = rv > v;
349  return RetVal(rv, c);
350  }
351 
352  static void ceil(Integer & d, const long double & v, const IntegerContext & c)
353  {
354  Integer::mpz_set_ld(d.d_value, std::ceil(v));
355  }
356 
357  static RetVal ceil(const long double & v, const IntegerContext & c)
358  {
359  return RetVal(std::ceil(v), c);
360  }
361  };
362 
363  template<> class nativeconversion_impl<Integer>
364  {
365  public:
366  static int toInt(const Integer & v)
367  {
368  return mpz_get_si(v.d_value);
369  }
370 
371  static unsigned int toUInt(const Integer & v)
372  {
373  return mpz_get_ui(v.d_value);
374  }
375 
376  static long toLong(const Integer & v)
377  {
378  return mpz_get_si(v.d_value);
379  }
380 
381  static unsigned long toULong(const Integer & v)
382  {
383  return mpz_get_ui(v.d_value);
384  }
385 
386  static long long toLongLong(const Integer & v)
387  {
388  return arithmetic::Integer::mpz_get_ll(v.d_value);
389  }
390 
391  static float toFloat(const Integer & v)
392  {
393  return mpz_get_d(v.d_value);
394  }
395 
396  static double toDouble(const Integer & v)
397  {
398  return mpz_get_d(v.d_value);
399  }
400 
401  static long double toLongDouble(const Integer & v)
402  {
403  return arithmetic::Integer::mpz_get_ld(v.d_value);
404  }
405  };
406 
407  template<class Data, template<typename, typename> class Op> class nativeconversion_impl<expressions::Expression<IntegerContext, Data, Op> >
408  {
409  public:
410  static int toInt(const expressions::Expression<IntegerContext, Data, Op> & v)
411  {
412  return nativeconversion_impl<Integer>::toInt(static_cast<Integer>(v));
413  }
414 
415  static unsigned int toUInt(const expressions::Expression<IntegerContext, Data, Op> & v)
416  {
417  return nativeconversion_impl<Integer>::toUInt(static_cast<Integer>(v));
418  }
419 
420  static long toLong(const expressions::Expression<IntegerContext, Data, Op> & v)
421  {
422  return nativeconversion_impl<Integer>::toLong(static_cast<Integer>(v));
423  }
424 
425  static unsigned long toULong(const expressions::Expression<IntegerContext, Data, Op> & v)
426  {
427  return nativeconversion_impl<Integer>::toULong(static_cast<Integer>(v));
428  }
429 
430  static long long toLongLong(const expressions::Expression<IntegerContext, Data, Op> & v)
431  {
432  return nativeconversion_impl<Integer>::toLongLong(static_cast<Integer>(v));
433  }
434 
435  static float toFloat(const expressions::Expression<IntegerContext, Data, Op> & v)
436  {
437  return nativeconversion_impl<Integer>::toFloat(static_cast<Integer>(v));
438  }
439 
440  static double toDouble(const expressions::Expression<IntegerContext, Data, Op> & v)
441  {
442  return nativeconversion_impl<Integer>::toDouble(static_cast<Integer>(v));
443  }
444 
445  static long double toLongDouble(const expressions::Expression<IntegerContext, Data, Op> & v)
446  {
447  return nativeconversion_impl<Integer>::toLongDouble(static_cast<Integer>(v));
448  }
449  };
450 
451  // Implementation for RealContext
452 
453  template<> class conversion_impl<signed int, RealContext>
454  {
455  public:
457  typedef Real RetVal_Frac;
458  typedef void RetVal_Floor;
459  typedef void RetVal_Ceil;
460  typedef void RetVal_Round;
461  typedef void RetVal_Round2;
462 
463  static void convert(Real & d, signed int v, const RealContext & c)
464  {
465  mpfr_set_si(d.d_value, v, MPFR_RNDN);
466  }
467 
468  static RetVal convert(signed int v, const RealContext & c)
469  {
470  return RetVal(v, c);
471  }
472 
473  static void convert_frac(Real & d, signed int v1, signed int v2, const RealContext & c)
474  {
475  mpfr_set_si(d.d_value, v1, MPFR_RNDN);
476  Real t((signed long)v2, c);
477  d /= t;
478  }
479 
480  static RetVal_Frac convert_frac(signed int v1, signed int v2, const RealContext & c)
481  {
482  Real t1((signed long)v1, c), t2((signed long)v2, c);
483  t1 /= t2;
484  return t1;
485  }
486  };
487 
488  template<> class conversion_impl<unsigned int, RealContext>
489  {
490  public:
492  typedef Real RetVal_Frac;
493  typedef void RetVal_Floor;
494  typedef void RetVal_Ceil;
495  typedef void RetVal_Round;
496  typedef void RetVal_Round2;
497 
498  static void convert(Real & d, unsigned int v, const RealContext & c)
499  {
500  mpfr_set_ui(d.d_value, v, MPFR_RNDN);
501  }
502 
503  static RetVal convert(unsigned int v, const RealContext & c)
504  {
505  return RetVal(v, c);
506  }
507 
508  static void convert_frac(Real & d, unsigned int v1, unsigned int v2, const RealContext & c)
509  {
510  mpfr_set_ui(d.d_value, v1, MPFR_RNDN);
511  Real t((unsigned long)v2, c);
512  d /= t;
513  }
514 
515  static RetVal_Frac convert_frac(unsigned int v1, unsigned int v2, const RealContext & c)
516  {
517  Real t1((unsigned long)v1, c), t2((unsigned long)v2, c);
518  t1 /= t2;
519  return t1;
520  }
521  };
522 
523  template<> class conversion_impl<signed long, RealContext>
524  {
525  public:
527  typedef Real RetVal_Frac;
528  typedef void RetVal_Floor;
529  typedef void RetVal_Ceil;
530  typedef void RetVal_Round;
531  typedef void RetVal_Round2;
532 
533  static void convert(Real & d, signed long v, const RealContext & c)
534  {
535  mpfr_set_si(d.d_value, v, MPFR_RNDN);
536  }
537 
538  static RetVal convert(signed long v, const RealContext & c)
539  {
540  return RetVal(v, c);
541  }
542 
543  static void convert_frac(Real & d, signed long v1, signed long v2, const RealContext & c)
544  {
545  mpfr_set_si(d.d_value, v1, MPFR_RNDN);
546  Real t(v2, c);
547  d /= t;
548  }
549 
550  static RetVal_Frac convert_frac(signed long v1, signed long v2, const RealContext & c)
551  {
552  Real t1(v1, c), t2(v2, c);
553  t1 /= t2;
554  return t1;
555  }
556  };
557 
558  template<> class conversion_impl<unsigned long, RealContext>
559  {
560  public:
562  typedef Real RetVal_Frac;
563  typedef void RetVal_Floor;
564  typedef void RetVal_Ceil;
565  typedef void RetVal_Round;
566  typedef void RetVal_Round2;
567 
568  static void convert(Real & d, unsigned long v, const RealContext & c)
569  {
570  mpfr_set_ui(d.d_value, v, MPFR_RNDN);
571  }
572 
573  static RetVal convert(unsigned long v, const RealContext & c)
574  {
575  return RetVal(v, c);
576  }
577 
578  static void convert_frac(Real & d, unsigned long v1, unsigned long v2, const RealContext & c)
579  {
580  mpfr_set_ui(d.d_value, v1, MPFR_RNDN);
581  Real t(v2, c);
582  d /= t;
583  }
584 
585  static RetVal_Frac convert_frac(unsigned long v1, unsigned long v2, const RealContext & c)
586  {
587  Real t1(v1, c), t2(v2, c);
588  t1 /= t2;
589  return t1;
590  }
591  };
592 
593  template<> class conversion_impl<long long, RealContext>
594  {
595  public:
597  typedef Real RetVal_Frac;
598  typedef void RetVal_Floor;
599  typedef void RetVal_Ceil;
600  typedef void RetVal_Round;
601  typedef void RetVal_Round2;
602 
603  static void convert(Real & d, long long v, const RealContext & c)
604  {
605  Real::mpfr_set_ll(d.d_value, v, MPFR_RNDN);
606  }
607 
608  static RetVal convert(long long v, const RealContext & c)
609  {
610  return RetVal(v, c);
611  }
612 
613  static void convert_frac(Real & d, long long v1, long long v2, const RealContext & c)
614  {
615  Real::mpfr_set_ll(d.d_value, v1, MPFR_RNDN);
616  Real t(v2, c);
617  d /= t;
618  }
619 
620  static RetVal_Frac convert_frac(long long v1, long long v2, const RealContext & c)
621  {
622  Real t1(v1, c), t2(v2, c);
623  t1 /= t2;
624  return t1;
625  }
626  };
627 
628  template<> class conversion_impl<float, RealContext>
629  {
630  public:
632  typedef Real RetVal_Frac;
633  typedef void RetVal_Floor;
634  typedef void RetVal_Ceil;
635  typedef void RetVal_Round;
636  typedef void RetVal_Round2;
637 
638  static void convert(Real & d, float v, const RealContext & c)
639  {
640  mpfr_set_d(d.d_value, v, MPFR_RNDN);
641  }
642 
643  static RetVal convert(float v, const RealContext & c)
644  {
645  return RetVal(v, c);
646  }
647 
648  static void convert_frac(Real & d, float v1, float v2, const RealContext & c)
649  {
650  mpfr_set_d(d.d_value, v1, MPFR_RNDN);
651  Real t(v2, c);
652  d /= t;
653  }
654 
655  static RetVal_Frac convert_frac(float v1, float v2, const RealContext & c)
656  {
657  Real t1(v1, c), t2(v2, c);
658  t1 /= t2;
659  return t1;
660  }
661  };
662 
663  template<> class conversion_impl<double, RealContext>
664  {
665  public:
667  typedef Real RetVal_Frac;
668  typedef void RetVal_Floor;
669  typedef void RetVal_Ceil;
670  typedef void RetVal_Round;
671  typedef void RetVal_Round2;
672 
673  static void convert(Real & d, double v, const RealContext & c)
674  {
675  mpfr_set_d(d.d_value, v, MPFR_RNDN);
676  }
677 
678  static RetVal convert(double v, const RealContext & c)
679  {
680  return RetVal(v, c);
681  }
682 
683  static void convert_frac(Real & d, double v1, double v2, const RealContext & c)
684  {
685  mpfr_set_d(d.d_value, v1, MPFR_RNDN);
686  Real t(v2, c);
687  d /= t;
688  }
689 
690  static RetVal_Frac convert_frac(double v1, double v2, const RealContext & c)
691  {
692  Real t1(v1, c), t2(v2, c);
693  t1 /= t2;
694  return t1;
695  }
696  };
697 
698  template<> class conversion_impl<long double, RealContext>
699  {
700  public:
702  typedef Real RetVal_Frac;
703  typedef void RetVal_Floor;
704  typedef void RetVal_Ceil;
705  typedef void RetVal_Round;
706  typedef void RetVal_Round2;
707 
708  static void convert(Real & d, long double v, const RealContext & c)
709  {
710  mpfr_set_ld(d.d_value, v, MPFR_RNDN);
711  }
712 
713  static RetVal convert(long double v, const RealContext & c)
714  {
715  return RetVal(v, c);
716  }
717 
718  static void convert_frac(Real & d, long double v1, long double v2, const RealContext & c)
719  {
720  mpfr_set_ld(d.d_value, v1, MPFR_RNDN);
721  Real t(v2, c);
722  d /= t;
723  }
724 
725  static RetVal_Frac convert_frac(long double v1, long double v2, const RealContext & c)
726  {
727  Real t1(v1, c), t2(v2, c);
728  t1 /= t2;
729  return t1;
730  }
731  };
732 
734  {
735  public:
738  typedef Real RetVal_Frac;
739  typedef void RetVal_Floor;
740  typedef void RetVal_Ceil;
741  typedef void RetVal_Round;
742  typedef void RetVal_Round2;
743 
744  static void convert(Real & d, const Integer & v, const RealContext & c)
745  {
746  mpfr_set_z(d.d_value, v.d_value, MPFR_RNDN);
747  }
748 
749  static RetVal convert(const Integer & v, const RealContext & c)
750  {
751  return RetVal(expressions::make_expression<IntegerContext>(v), c);
752  }
753 
754  static void convert_frac(Real & d, const Integer & v1, const Integer & v2, const RealContext & c)
755  {
756  mpfr_set_z(d.d_value, v1.d_value, MPFR_RNDN);
757  Real t(v2, c);
758  d /= t;
759  }
760 
761  static RetVal_Frac convert_frac(const Integer & v1, const Integer & v2, const RealContext & c)
762  {
763  Real t1(v1, c), t2(v2, c);
764  t1 /= t2;
765  return t1;
766  }
767  };
768 
770  {
771  public:
774  typedef void RetVal_Frac;
783 
784  static void convert(Integer & d, const Real & v, const IntegerContext & c)
785  {
786  mpfr_get_z(d.d_value, v.d_value, MPFR_RNDD);
787  }
788 
789  static RetVal convert(const Real & v, const IntegerContext & c)
790  {
791  return RetVal(expressions::make_expression<RealContext>(v), implementation::g_intcontext);
792  }
793 
794  static void floor(Integer & d, const Real & v, const IntegerContext & c)
795  {
796  mpfr_get_z(d.d_value, v.d_value, MPFR_RNDD);
797  }
798 
799  static RetVal_Floor floor(const Real & v, const IntegerContext & c)
800  {
801  return RetVal_Floor(expressions::make_expression<RealContext>(v), implementation::g_intcontext);
802  }
803 
804  static void round(Integer & d, const Real & v, const IntegerContext & c)
805  {
806  mpfr_get_z(d.d_value, v.d_value, MPFR_RNDN);
807  }
808 
809  static RetVal_Round round(const Real & v, const IntegerContext & c)
810  {
811  return RetVal_Round(expressions::make_expression<RealContext>(v), implementation::g_intcontext);
812  }
813 
814  static void round(Integer & d, const Real & v, bool & up, const IntegerContext & c)
815  {
816  mpfr_get_z(d.d_value, v.d_value, MPFR_RNDN);
817  mpz_t tmp;
818  mpz_init(tmp);
819  mpfr_get_z(tmp, v.d_value, MPFR_RNDD);
820  up = mpz_cmp(tmp, d.d_value) != 0;
821  mpz_clear(tmp);
822  }
823 
824  static RetVal_Round2 round(const Real & v, bool & up, const IntegerContext & c)
825  {
826  return RetVal_Round2(expressions::make_expression<RealContext>(v),
829  expressions::NoneOp> >(up, implementation::g_intcontext));
830  }
831 
832  static void ceil(Integer & d, const Real & v, const IntegerContext & c)
833  {
834  mpfr_get_z(d.d_value, v.d_value, MPFR_RNDU);
835  }
836 
837  static RetVal_Ceil ceil(const Real & v, const IntegerContext & c)
838  {
839  return RetVal_Ceil(expressions::make_expression<RealContext>(v), implementation::g_intcontext);
840  }
841  };
842 
843  template<> class conversion_impl<Real, RealContext>
848  {
849  public:
850  typedef Real RetVal;
851  typedef Real RetVal_Frac;
852  typedef void RetVal_Floor;
853  typedef void RetVal_Ceil;
854  typedef void RetVal_Round;
855  typedef void RetVal_Round2;
856 
857  static void convert(Real & d, const Real & v, const RealContext & c)
858  // Nothing special: no precision change
859  {
860  d = v;
861  }
862 
863  static RetVal convert(const Real & v, const RealContext & c)
864  {
865  return Real(v, c);
866  }
867 
868  static void convert_frac(Real & d, const Real & v1, const Real & v2, const RealContext & c)
869  // Nothing special: no precision change
870  {
871  d = v1 / v2;
872  }
873 
874  static RetVal_Frac convert_frac(const Real & v1, const Real & v2, const RealContext & c)
875  // Adjust precision of result!
876  {
877  Real r(c);
878  r = v1 / v2;
879  return r;
880  }
881  };
882 
883  template<> class nativeconversion_impl<Real>
884  {
885  public:
886  static int toInt(const Real & v)
887  {
888  return mpfr_get_si(v.d_value, MPFR_RNDD);
889  }
890 
891  static int toInt_Floor(const Real & v)
892  {
893  return mpfr_get_si(v.d_value, MPFR_RNDD);
894  }
895 
896  static int toInt_Round(const Real & v)
897  {
898  return mpfr_get_si(v.d_value, MPFR_RNDN);
899  }
900 
901  static int toInt_Round(const Real & v, bool & up)
902  {
903  int r = mpfr_get_si(v.d_value, MPFR_RNDN);
904  up = mpfr_cmp_si(v.d_value, r) < 0;
905  return r;
906  }
907 
908  static int toInt_Ceil(const Real & v)
909  {
910  return mpfr_get_si(v.d_value, MPFR_RNDU);
911  }
912 
913  static unsigned int toUInt(const Real & v)
914  {
915  return mpfr_get_ui(v.d_value, MPFR_RNDD);
916  }
917 
918  static unsigned int toUInt_Floor(const Real & v)
919  {
920  return mpfr_get_ui(v.d_value, MPFR_RNDD);
921  }
922 
923  static unsigned int toUInt_Round(const Real & v)
924  {
925  return mpfr_get_ui(v.d_value, MPFR_RNDN);
926  }
927 
928  static unsigned int toUInt_Round(const Real & v, bool & up)
929  {
930  unsigned int r = mpfr_get_ui(v.d_value, MPFR_RNDN);
931  up = mpfr_cmp_ui(v.d_value, r) < 0;
932  return r;
933  }
934 
935  static unsigned int toUInt_Ceil(const Real & v)
936  {
937  return mpfr_get_ui(v.d_value, MPFR_RNDU);
938  }
939 
940  static long toLong(const Real & v)
941  {
942  return mpfr_get_si(v.d_value, MPFR_RNDD);
943  }
944 
945  static long toLong_Floor(const Real & v)
946  {
947  return mpfr_get_si(v.d_value, MPFR_RNDD);
948  }
949 
950  static long toLong_Round(const Real & v)
951  {
952  return mpfr_get_si(v.d_value, MPFR_RNDN);
953  }
954 
955  static long toLong_Round(const Real & v, bool & up)
956  {
957  long r = mpfr_get_si(v.d_value, MPFR_RNDN);
958  up = mpfr_cmp_si(v.d_value, r) < 0;
959  return r;
960  }
961 
962  static long toLong_Ceil(const Real & v)
963  {
964  return mpfr_get_si(v.d_value, MPFR_RNDU);
965  }
966 
967  static unsigned long toULong(const Real & v)
968  {
969  return mpfr_get_ui(v.d_value, MPFR_RNDD);
970  }
971 
972  static unsigned long toULong_Floor(const Real & v)
973  {
974  return mpfr_get_ui(v.d_value, MPFR_RNDD);
975  }
976 
977  static unsigned long toULong_Round(const Real & v)
978  {
979  return mpfr_get_ui(v.d_value, MPFR_RNDN);
980  }
981 
982  static unsigned long toULong_Round(const Real & v, bool & up)
983  {
984  unsigned long r = mpfr_get_ui(v.d_value, MPFR_RNDN);
985  up = mpfr_cmp_ui(v.d_value, r) < 0;
986  return r;
987  }
988 
989  static unsigned long toULong_Ceil(const Real & v)
990  {
991  return mpfr_get_ui(v.d_value, MPFR_RNDU);
992  }
993 
994  static long long toLongLong(const Real & v)
995  {
996  return Real::mpfr_get_ll(v.d_value, MPFR_RNDD);
997  }
998 
999  static long long toLongLong_Floor(const Real & v)
1000  {
1001  return Real::mpfr_get_ll(v.d_value, MPFR_RNDD);
1002  }
1003 
1004  static long long toLongLong_Round(const Real & v)
1005  {
1006  return Real::mpfr_get_ll(v.d_value, MPFR_RNDN);
1007  }
1008 
1009  static long long toLongLong_Round(const Real & v, bool & up)
1010  {
1011  return Real::mpfr_get_ll(v.d_value, MPFR_RNDN, up);
1012  }
1013 
1014  static long long toLongLong_Ceil(const Real & v)
1015  {
1016  return Real::mpfr_get_ll(v.d_value, MPFR_RNDU);
1017  }
1018 
1019  static float toFloat(const Real & v)
1020  {
1021  return mpfr_get_d(v.d_value, MPFR_RNDN);
1022  }
1023 
1024  static double toDouble(const Real & v)
1025  {
1026  return mpfr_get_d(v.d_value, MPFR_RNDN);
1027  }
1028 
1029  static long double toLongDouble(const Real & v)
1030  {
1031  return mpfr_get_ld(v.d_value, MPFR_RNDN);
1032  }
1033  };
1034  }
1035 
1036  namespace traits
1037  {
1038  template<class Data, template<typename, typename> class Op>
1039  struct type_traits<expressions::Expression<IntegerContext, Data, Op> >
1040  {
1041  enum
1042  {
1043  is_number = true,
1044  is_cputype = false,
1045  is_realtype = false,
1046  is_inttype = true,
1047  is_string = false,
1048  is_cpp_string = false,
1049  is_c_string = false,
1050  is_exact = true,
1051  has_uniform_rng = true,
1052  has_context = true,
1053  is_native = false,
1054  is_modulo = false,
1055  has_infinity = false,
1056  is_variable_precision = false,
1057  has_squareroot = false,
1058  has_full_power = false,
1059  has_special_fns = false,
1060  has_huge_exponent = false,
1061  has_constants = false,
1062  has_trigonometric = false
1063  };
1064 
1065  typedef IntegerContext Context;
1066  typedef Integer PromoteType;
1068  };
1069 
1070  template<class Data, template<typename, typename> class Op>
1071  struct type_traits<expressions::Expression<RealContext, Data, Op> >
1072  {
1073  enum
1074  {
1075  is_number = true,
1076  is_cputype = false,
1077  is_realtype = true,
1078  is_inttype = false,
1079  is_string = false,
1080  is_cpp_string = false,
1081  is_c_string = false,
1082  is_exact = false,
1083  has_uniform_rng = true,
1084  has_context = true,
1085  is_native = false,
1086  is_modulo = false,
1087  has_infinity = true,
1088  is_variable_precision = true,
1089  has_squareroot = true,
1090  has_full_power = true,
1091  has_special_fns = true,
1092  has_huge_exponent = true,
1093  has_constants = true,
1094  has_trigonometric = true
1095  };
1096 
1097  typedef RealContext Context;
1098  typedef Real PromoteType;
1100  };
1101  }
1102 
1103  namespace implementation
1104  {
1105  template<>
1107  {
1108  public:
1109  typedef Integer RetVal1;
1110  typedef Integer RetVal2;
1111 
1112  static bool convert(Integer & res, const std::string & s, const IntegerContext & c);
1113  static bool convert(Integer & res, const char * s, const IntegerContext & c);
1114 
1115  static RetVal1 convert(const std::string & s, const IntegerContext & c)
1116  {
1117  Integer res;
1118  convert(res, s, c);
1119  return res;
1120  }
1121 
1122  static RetVal2 convert(const char * s, const IntegerContext & c)
1123  {
1124  Integer res;
1125  convert(res, s, c);
1126  return res;
1127  }
1128  };
1129 
1130  template<>
1132  {
1133  public:
1134  typedef std::string RetVal;
1135 
1136  static RetVal convert(const Integer &);
1137  static RetVal convert(const Integer &, unsigned);
1138  static void convert(std::string &, const Integer &);
1139  static void convert(std::string &, const Integer &, unsigned);
1140  };
1141 
1142  template<>
1144  {
1145  public:
1146  typedef Real RetVal1;
1147  typedef Real RetVal2;
1148 
1149  static bool convert(Real & res, const std::string & s, const RealContext & c);
1150  static bool convert(Real & res, const char * s, const RealContext & c);
1151 
1152  static RetVal1 convert(const std::string & s, const RealContext & c)
1153  {
1154  Real res(c);
1155  convert(res, s, c);
1156  return res;
1157  }
1158 
1159  static RetVal2 convert(const char * s, const RealContext & c)
1160  {
1161  Real res(c);
1162  convert(res, s, c);
1163  return res;
1164  }
1165  };
1166 
1167  template<>
1169  {
1170  public:
1171  typedef std::string RetVal;
1172 
1173  static RetVal convert(const Real &);
1174  static RetVal convert(const Real &, unsigned);
1175  static void convert(std::string &, const Real &);
1176  static void convert(std::string &, const Real &, unsigned);
1177  };
1178 
1179  #define MAKE_INTEGER_DEFS(Op1, Op2) \
1180  template<> \
1181  struct binary_operation_impl<Integer, Integer, Op1> \
1182  { \
1183  enum { supported = true, intermediate_expression = true }; \
1184  typedef expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>, \
1185  expressions::Wrapper<IntegerContext> >, Op2> IntermediateType; \
1186  typedef Integer ResultType; \
1187  }; \
1188  \
1189  template<template<typename, typename> class O1, typename D1> \
1190  struct binary_operation_impl<expressions::Expression<IntegerContext, D1, O1>, Integer, Op1> \
1191  { \
1192  enum { supported = true, intermediate_expression = true }; \
1193  typedef expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, D1, O1>, \
1194  expressions::Wrapper<IntegerContext> >, Op2> IntermediateType; \
1195  typedef Integer ResultType; \
1196  }; \
1197  \
1198  template<template<typename, typename> class O2, typename D2> \
1199  struct binary_operation_impl<Integer, expressions::Expression<IntegerContext, D2, O2>, Op1> \
1200  { \
1201  enum { supported = true, intermediate_expression = true }; \
1202  typedef expressions::Expression<IntegerContext, std::pair<expressions::Wrapper<IntegerContext>, \
1203  expressions::Expression<IntegerContext, D2, O2> >, Op2> IntermediateType; \
1204  typedef Integer ResultType; \
1205  }; \
1206  \
1207  template<template<typename, typename> class O1, typename D1, template<typename, typename> class O2, typename D2> \
1208  struct binary_operation_impl<expressions::Expression<IntegerContext, D1, O1>, expressions::Expression<IntegerContext, D2, O2>, Op1> \
1209  { \
1210  enum { supported = true, intermediate_expression = true }; \
1211  typedef expressions::Expression<IntegerContext, std::pair<expressions::Expression<IntegerContext, D1, O1>, \
1212  expressions::Expression<IntegerContext, D2, O2> >, Op2> IntermediateType; \
1213  typedef Integer ResultType; \
1214  }; \
1215 
1216  MAKE_INTEGER_DEFS(arithmetic::op::addition, expressions::AddOp)
1217  MAKE_INTEGER_DEFS(arithmetic::op::subtraction, expressions::SubOp)
1218  MAKE_INTEGER_DEFS(arithmetic::op::multiplication, expressions::MulOp)
1219  MAKE_INTEGER_DEFS(arithmetic::op::division, expressions::DivOp)
1220  MAKE_INTEGER_DEFS(arithmetic::op::modulo, expressions::ModOp)
1221  #undef MAKE_INTEGER_DEFS
1222 
1223  template<>
1225  {
1226  enum { supported = true, intermediate_expression = true };
1229  typedef Integer ResultType;
1230  };
1231 
1232  template<template<typename, typename> class O, class D>
1233  struct unary_operation_impl<expressions::Expression<IntegerContext, D, O>, arithmetic::op::negation>
1234  {
1235  enum { supported = true, intermediate_expression = true };
1238  typedef Integer ResultType;
1239  };
1240 
1241  #define MAKE_REAL_DEFS(Op1, Op2) \
1242  template<> \
1243  struct binary_operation_impl<Real, Real, Op1> \
1244  { \
1245  enum { supported = true, intermediate_expression = true }; \
1246  typedef expressions::Expression<RealContext, std::pair<expressions::Wrapper<RealContext>, \
1247  expressions::Wrapper<RealContext> >, Op2> IntermediateType; \
1248  typedef Real ResultType; \
1249  }; \
1250  \
1251  template<template<typename, typename> class O1, typename D1> \
1252  struct binary_operation_impl<expressions::Expression<RealContext, D1, O1>, Real, Op1> \
1253  { \
1254  enum { supported = true, intermediate_expression = true }; \
1255  typedef expressions::Expression<RealContext, std::pair<expressions::Expression<RealContext, D1, O1>, \
1256  expressions::Wrapper<RealContext> >, Op2> IntermediateType; \
1257  typedef Real ResultType; \
1258  }; \
1259  \
1260  template<template<typename, typename> class O2, typename D2> \
1261  struct binary_operation_impl<Real, expressions::Expression<RealContext, D2, O2>, Op1> \
1262  { \
1263  enum { supported = true, intermediate_expression = true }; \
1264  typedef expressions::Expression<RealContext, std::pair<expressions::Wrapper<RealContext>, \
1265  expressions::Expression<RealContext, D2, O2> >, Op2> IntermediateType; \
1266  typedef Real ResultType; \
1267  }; \
1268  \
1269  template<template<typename, typename> class O1, typename D1, template<typename, typename> class O2, typename D2> \
1270  struct binary_operation_impl<expressions::Expression<RealContext, D1, O1>, expressions::Expression<RealContext, D2, O2>, Op1> \
1271  { \
1272  enum { supported = true, intermediate_expression = true }; \
1273  typedef expressions::Expression<RealContext, std::pair<expressions::Expression<RealContext, D1, O1>, \
1274  expressions::Expression<RealContext, D2, O2> >, Op2> IntermediateType; \
1275  typedef Real ResultType; \
1276  }; \
1277 
1279  MAKE_REAL_DEFS(arithmetic::op::subtraction, expressions::SubOp)
1280  MAKE_REAL_DEFS(arithmetic::op::multiplication, expressions::MulOp)
1281  MAKE_REAL_DEFS(arithmetic::op::division, expressions::DivOp)
1282  MAKE_REAL_DEFS(arithmetic::op::modulo, expressions::ModOp)
1283  #undef MAKE_REAL_DEFS
1284 
1285  template<>
1287  {
1288  enum { supported = true, intermediate_expression = true };
1290  typedef Real ResultType;
1291  };
1292 
1293  template<template<typename, typename> class O, class D>
1294  struct unary_operation_impl<expressions::Expression<RealContext, D, O>, arithmetic::op::negation>
1295  {
1296  enum { supported = true, intermediate_expression = true };
1298  typedef Real ResultType;
1299  };
1300  }
1301  }
1302 }
1303 
1304 #endif
Returns the sum of the operands.
Converts the argument to the destination type. Uses the context stored in the operator.
Simply provides the data without any modifications.
Provides information on the result of an unary arithmetic operation.
Definition: arithmetic.hpp:138
Returns the negative of the operand.
Provides conversion implementation from type SourceType to DestContext::Type.
Definition: arithmetic.hpp:713
void convert(typename DestContext::Type &dst, const SourceType &src, const DestContext &context)
Converts the value in src to the type described by context and stores the result in dst...
Definition: arithmetic.hpp:734
Provides facilities to convert strings to types.
Provides facilities to convert types to std::strings.
Converts the argument to the destination type by rounding. Uses the context stored in the operator an...
Implementation backend for conversions from context types to native types.
Definition: arithmetic.hpp:994
Converts the argument to the destination type by rounding down (floor). Uses the context stored in th...
Represents an arbitrary precision floating point value.
Converts the argument to the destination type by rounding up (ceil). Uses the context stored in the o...
Represents an arithmetic context for arbitrary precision floating point values.
Converts the argument to the destination type by rounding. Uses the context stored in the operator...
Provides information on arithmetic (and string) types.
Definition: arithmetic.hpp:184
Represents an arbitrary precision integer.
Wraps a variable to behave similarly to an Expression<> object.
Represents an arithmetic context for arbitrary precision integer.