]> Shamusworld >> Repos - architektonas/blob - fparser/mpfr/MpfrFloat.cc
Bugfixes related to removing Snapper class.
[architektonas] / fparser / mpfr / MpfrFloat.cc
1 #include "MpfrFloat.hh"
2 #include <stdio.h>
3 #include <mpfr.h>
4 #include <deque>
5 #include <vector>
6 #include <cstring>
7 #include <cassert>
8
9 //===========================================================================
10 // Auxiliary structs
11 //===========================================================================
12 struct MpfrFloat::MpfrFloatData
13 {
14     unsigned mRefCount;
15     MpfrFloatData* nextFreeNode;
16     mpfr_t mFloat;
17
18     MpfrFloatData(): mRefCount(1), nextFreeNode(0) {}
19 };
20
21 class MpfrFloat::MpfrFloatDataContainer
22 {
23     unsigned long mDefaultPrecision;
24     std::deque<MpfrFloatData> mData;
25     MpfrFloatData* mFirstFreeNode;
26
27     MpfrFloatData
28     *mConst_0, *mConst_pi, *mConst_e, *mConst_log2, *mConst_epsilon;
29
30     void recalculateEpsilon()
31     {
32         mpfr_set_si(mConst_epsilon->mFloat, 1, GMP_RNDN);
33         mpfr_div_2ui(mConst_epsilon->mFloat, mConst_epsilon->mFloat,
34                      mDefaultPrecision*7/8 - 1, GMP_RNDN);
35     }
36
37  public:
38     MpfrFloatDataContainer():
39         mDefaultPrecision(256), mFirstFreeNode(0),
40         mConst_pi(0), mConst_e(0), mConst_log2(0), mConst_epsilon(0)
41     {}
42
43     ~MpfrFloatDataContainer()
44     {
45         for(size_t i = 0; i < mData.size(); ++i)
46             mpfr_clear(mData[i].mFloat);
47     }
48
49     MpfrFloatData* allocateMpfrFloatData(bool initToZero)
50     {
51         if(mFirstFreeNode)
52         {
53             MpfrFloatData* node = mFirstFreeNode;
54             mFirstFreeNode = node->nextFreeNode;
55             if(initToZero) mpfr_set_si(node->mFloat, 0, GMP_RNDN);
56             ++(node->mRefCount);
57             return node;
58         }
59
60         mData.push_back(MpfrFloatData());
61         mpfr_init2(mData.back().mFloat, mDefaultPrecision);
62         if(initToZero) mpfr_set_si(mData.back().mFloat, 0, GMP_RNDN);
63         return &mData.back();
64     }
65
66     void releaseMpfrFloatData(MpfrFloatData* data)
67     {
68         if(--(data->mRefCount) == 0)
69         {
70             data->nextFreeNode = mFirstFreeNode;
71             mFirstFreeNode = data;
72         }
73     }
74
75     void setDefaultPrecision(unsigned long bits)
76     {
77         if(bits != mDefaultPrecision)
78         {
79             mDefaultPrecision = bits;
80             for(size_t i = 0; i < mData.size(); ++i)
81                 mpfr_prec_round(mData[i].mFloat, bits, GMP_RNDN);
82
83             if(mConst_pi) mpfr_const_pi(mConst_pi->mFloat, GMP_RNDN);
84             if(mConst_e)
85             {
86                 mpfr_set_si(mConst_e->mFloat, 1, GMP_RNDN);
87                 mpfr_exp(mConst_e->mFloat, mConst_e->mFloat, GMP_RNDN);
88             }
89             if(mConst_log2) mpfr_const_log2(mConst_log2->mFloat, GMP_RNDN);
90             if(mConst_epsilon) recalculateEpsilon();
91         }
92     }
93
94     unsigned long getDefaultPrecision() const
95     {
96         return mDefaultPrecision;
97     }
98
99     MpfrFloatData* const_0()
100     {
101         if(!mConst_0) mConst_0 = allocateMpfrFloatData(true);
102         return mConst_0;
103     }
104
105     MpfrFloat const_pi()
106     {
107         if(!mConst_pi)
108         {
109             mConst_pi = allocateMpfrFloatData(false);
110             mpfr_const_pi(mConst_pi->mFloat, GMP_RNDN);
111         }
112         return MpfrFloat(mConst_pi);
113     }
114
115     MpfrFloat const_e()
116     {
117         if(!mConst_e)
118         {
119             mConst_e = allocateMpfrFloatData(false);
120             mpfr_set_si(mConst_e->mFloat, 1, GMP_RNDN);
121             mpfr_exp(mConst_e->mFloat, mConst_e->mFloat, GMP_RNDN);
122         }
123         return MpfrFloat(mConst_e);
124     }
125
126     MpfrFloat const_log2()
127     {
128         if(!mConst_log2)
129         {
130             mConst_log2 = allocateMpfrFloatData(false);
131             mpfr_const_log2(mConst_log2->mFloat, GMP_RNDN);
132         }
133         return MpfrFloat(mConst_log2);
134     }
135
136     MpfrFloat const_epsilon()
137     {
138         if(!mConst_epsilon)
139         {
140             mConst_epsilon = allocateMpfrFloatData(false);
141             recalculateEpsilon();
142         }
143         return MpfrFloat(mConst_epsilon);
144     }
145 };
146
147
148 //===========================================================================
149 // Shared data
150 //===========================================================================
151 // This should ensure that the container is not accessed by any MpfrFloat
152 // instance before it has been constructed or after it has been destroyed
153 // (which might otherwise happen if MpfrFloat is instantiated globally.)
154 MpfrFloat::MpfrFloatDataContainer& MpfrFloat::mpfrFloatDataContainer()
155 {
156     static MpfrFloat::MpfrFloatDataContainer container;
157     return container;
158 }
159
160
161 //===========================================================================
162 // Auxiliary functions
163 //===========================================================================
164 void MpfrFloat::setDefaultMantissaBits(unsigned long bits)
165 {
166     mpfrFloatDataContainer().setDefaultPrecision(bits);
167 }
168
169 unsigned long MpfrFloat::getCurrentDefaultMantissaBits()
170 {
171     return mpfrFloatDataContainer().getDefaultPrecision();
172 }
173
174 inline void MpfrFloat::copyIfShared()
175 {
176     if(mData->mRefCount > 1)
177     {
178         --(mData->mRefCount);
179         MpfrFloatData* oldData = mData;
180         mData = mpfrFloatDataContainer().allocateMpfrFloatData(false);
181         mpfr_set(mData->mFloat, oldData->mFloat, GMP_RNDN);
182     }
183 }
184
185
186 //===========================================================================
187 // Constructors, destructor, assignment
188 //===========================================================================
189 MpfrFloat::MpfrFloat(DummyType):
190     mData(mpfrFloatDataContainer().allocateMpfrFloatData(false))
191 {}
192
193 MpfrFloat::MpfrFloat(MpfrFloatData* data):
194     mData(data)
195 {
196     assert(data != 0);
197     ++(mData->mRefCount);
198 }
199
200 MpfrFloat::MpfrFloat():
201     mData(mpfrFloatDataContainer().const_0())
202 {
203     ++(mData->mRefCount);
204 }
205
206 MpfrFloat::MpfrFloat(double value)
207 {
208     if(value == 0.0)
209     {
210         mData = mpfrFloatDataContainer().const_0();
211         ++(mData->mRefCount);
212     }
213     else
214     {
215         mData = mpfrFloatDataContainer().allocateMpfrFloatData(false);
216         mpfr_set_d(mData->mFloat, value, GMP_RNDN);
217     }
218 }
219
220 MpfrFloat::MpfrFloat(long double value)
221 {
222     if(value == 0.0L)
223     {
224         mData = mpfrFloatDataContainer().const_0();
225         ++(mData->mRefCount);
226     }
227     else
228     {
229         mData = mpfrFloatDataContainer().allocateMpfrFloatData(false);
230         mpfr_set_ld(mData->mFloat, value, GMP_RNDN);
231     }
232 }
233
234 MpfrFloat::MpfrFloat(long value)
235 {
236     if(value == 0)
237     {
238         mData = mpfrFloatDataContainer().const_0();
239         ++(mData->mRefCount);
240     }
241     else
242     {
243         mData = mpfrFloatDataContainer().allocateMpfrFloatData(false);
244         mpfr_set_si(mData->mFloat, value, GMP_RNDN);
245     }
246 }
247
248 MpfrFloat::MpfrFloat(int value)
249 {
250     if(value == 0)
251     {
252         mData = mpfrFloatDataContainer().const_0();
253         ++(mData->mRefCount);
254     }
255     else
256     {
257         mData = mpfrFloatDataContainer().allocateMpfrFloatData(false);
258         mpfr_set_si(mData->mFloat, value, GMP_RNDN);
259     }
260 }
261
262 MpfrFloat::MpfrFloat(const char* value, char** endptr):
263     mData(mpfrFloatDataContainer().allocateMpfrFloatData(false))
264 {
265     mpfr_strtofr(mData->mFloat, value, endptr, 0, GMP_RNDN);
266 }
267
268 MpfrFloat::~MpfrFloat()
269 {
270     mpfrFloatDataContainer().releaseMpfrFloatData(mData);
271 }
272
273 MpfrFloat::MpfrFloat(const MpfrFloat& rhs):
274     mData(rhs.mData)
275 {
276     ++(mData->mRefCount);
277 }
278
279 MpfrFloat& MpfrFloat::operator=(const MpfrFloat& rhs)
280 {
281     if(mData != rhs.mData)
282     {
283         mpfrFloatDataContainer().releaseMpfrFloatData(mData);
284         mData = rhs.mData;
285         ++(mData->mRefCount);
286     }
287     return *this;
288 }
289
290 MpfrFloat& MpfrFloat::operator=(double value)
291 {
292     if(value == 0.0)
293     {
294         mpfrFloatDataContainer().releaseMpfrFloatData(mData);
295         mData = mpfrFloatDataContainer().const_0();
296         ++(mData->mRefCount);
297     }
298     else
299     {
300         if(mData->mRefCount > 1)
301         {
302             --(mData->mRefCount);
303             mData = mpfrFloatDataContainer().allocateMpfrFloatData(false);
304         }
305         mpfr_set_d(mData->mFloat, value, GMP_RNDN);
306     }
307     return *this;
308 }
309
310 MpfrFloat& MpfrFloat::operator=(long double value)
311 {
312     if(value == 0.0L)
313     {
314         mpfrFloatDataContainer().releaseMpfrFloatData(mData);
315         mData = mpfrFloatDataContainer().const_0();
316         ++(mData->mRefCount);
317     }
318     else
319     {
320         if(mData->mRefCount > 1)
321         {
322             --(mData->mRefCount);
323             mData = mpfrFloatDataContainer().allocateMpfrFloatData(false);
324         }
325         mpfr_set_ld(mData->mFloat, value, GMP_RNDN);
326     }
327     return *this;
328 }
329
330 MpfrFloat& MpfrFloat::operator=(long value)
331 {
332     if(value == 0)
333     {
334         mpfrFloatDataContainer().releaseMpfrFloatData(mData);
335         mData = mpfrFloatDataContainer().const_0();
336         ++(mData->mRefCount);
337     }
338     else
339     {
340         if(mData->mRefCount > 1)
341         {
342             --(mData->mRefCount);
343             mData = mpfrFloatDataContainer().allocateMpfrFloatData(false);
344         }
345         mpfr_set_si(mData->mFloat, value, GMP_RNDN);
346     }
347     return *this;
348 }
349
350 MpfrFloat& MpfrFloat::operator=(int value)
351 {
352     if(value == 0)
353     {
354         mpfrFloatDataContainer().releaseMpfrFloatData(mData);
355         mData = mpfrFloatDataContainer().const_0();
356         ++(mData->mRefCount);
357     }
358     else
359     {
360         if(mData->mRefCount > 1)
361         {
362             --(mData->mRefCount);
363             mData = mpfrFloatDataContainer().allocateMpfrFloatData(false);
364         }
365         mpfr_set_si(mData->mFloat, value, GMP_RNDN);
366     }
367     return *this;
368 }
369
370 /*
371 MpfrFloat& MpfrFloat::operator=(const char* value)
372 {
373     if(mData->mRefCount > 1)
374     {
375         --(mData->mRefCount);
376         mData = mpfrFloatDataContainer().allocateMpfrFloatData(false);
377     }
378
379     mpfr_set_str(mData->mFloat, value, 10, GMP_RNDN);
380     return *this;
381 }
382 */
383
384 void MpfrFloat::parseValue(const char* value)
385 {
386     copyIfShared();
387     mpfr_set_str(mData->mFloat, value, 10, GMP_RNDN);
388 }
389
390 void MpfrFloat::parseValue(const char* value, char** endptr)
391 {
392     copyIfShared();
393     mpfr_strtofr(mData->mFloat, value, endptr, 0, GMP_RNDN);
394 }
395
396
397 //===========================================================================
398 // Data getters
399 //===========================================================================
400 template<>
401 void MpfrFloat::get_raw_mpfr_data<mpfr_t>(mpfr_t& dest_mpfr_t)
402 {
403     std::memcpy(&dest_mpfr_t, mData->mFloat, sizeof(mpfr_t));
404 }
405
406 const char* MpfrFloat::getAsString(unsigned precision) const
407 {
408 #if(MPFR_VERSION_MAJOR < 2 || (MPFR_VERSION_MAJOR == 2 && MPFR_VERSION_MINOR < 4))
409     static const char* retval =
410         "[mpfr_snprintf() is not supported in mpfr versions prior to 2.4]";
411     return retval;
412 #else
413     static std::vector<char> str;
414     str.resize(precision+30);
415     mpfr_snprintf(&(str[0]), precision+30, "%.*RNg", precision, mData->mFloat);
416     return &(str[0]);
417 #endif
418 }
419
420 bool MpfrFloat::isInteger() const
421 {
422     return mpfr_integer_p(mData->mFloat) != 0;
423 }
424
425 long MpfrFloat::toInt() const
426 {
427     return mpfr_get_si(mData->mFloat, GMP_RNDN);
428 }
429
430 double MpfrFloat::toDouble() const
431 {
432     return mpfr_get_d(mData->mFloat, GMP_RNDN);
433 }
434
435
436 //===========================================================================
437 // Modifying operators
438 //===========================================================================
439 MpfrFloat& MpfrFloat::operator+=(const MpfrFloat& rhs)
440 {
441     copyIfShared();
442     mpfr_add(mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN);
443     return *this;
444 }
445
446 MpfrFloat& MpfrFloat::operator+=(double value)
447 {
448     copyIfShared();
449     mpfr_add_d(mData->mFloat, mData->mFloat, value, GMP_RNDN);
450     return *this;
451 }
452
453 MpfrFloat& MpfrFloat::operator-=(const MpfrFloat& rhs)
454 {
455     copyIfShared();
456     mpfr_sub(mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN);
457     return *this;
458 }
459
460 MpfrFloat& MpfrFloat::operator-=(double value)
461 {
462     copyIfShared();
463     mpfr_sub_d(mData->mFloat, mData->mFloat, value, GMP_RNDN);
464     return *this;
465 }
466
467 MpfrFloat& MpfrFloat::operator*=(const MpfrFloat& rhs)
468 {
469     copyIfShared();
470     mpfr_mul(mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN);
471     return *this;
472 }
473
474 MpfrFloat& MpfrFloat::operator*=(double value)
475 {
476     copyIfShared();
477     mpfr_mul_d(mData->mFloat, mData->mFloat, value, GMP_RNDN);
478     return *this;
479 }
480
481 MpfrFloat& MpfrFloat::operator/=(const MpfrFloat& rhs)
482 {
483     copyIfShared();
484     mpfr_div(mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN);
485     return *this;
486 }
487
488 MpfrFloat& MpfrFloat::operator/=(double value)
489 {
490     copyIfShared();
491     mpfr_div_d(mData->mFloat, mData->mFloat, value, GMP_RNDN);
492     return *this;
493 }
494
495 MpfrFloat& MpfrFloat::operator%=(const MpfrFloat& rhs)
496 {
497     copyIfShared();
498     mpfr_fmod(mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN);
499     return *this;
500 }
501
502
503 //===========================================================================
504 // Modifying functions
505 //===========================================================================
506 void MpfrFloat::negate()
507 {
508     copyIfShared();
509     mpfr_neg(mData->mFloat, mData->mFloat, GMP_RNDN);
510 }
511
512 void MpfrFloat::abs()
513 {
514     copyIfShared();
515     mpfr_abs(mData->mFloat, mData->mFloat, GMP_RNDN);
516 }
517
518
519 //===========================================================================
520 // Non-modifying operators
521 //===========================================================================
522 MpfrFloat MpfrFloat::operator+(const MpfrFloat& rhs) const
523 {
524     MpfrFloat retval(kNoInitialization);
525     mpfr_add(retval.mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN);
526     return retval;
527 }
528
529 MpfrFloat MpfrFloat::operator+(double value) const
530 {
531     MpfrFloat retval(kNoInitialization);
532     mpfr_add_d(retval.mData->mFloat, mData->mFloat, value, GMP_RNDN);
533     return retval;
534 }
535
536 MpfrFloat MpfrFloat::operator-(const MpfrFloat& rhs) const
537 {
538     MpfrFloat retval(kNoInitialization);
539     mpfr_sub(retval.mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN);
540     return retval;
541 }
542
543 MpfrFloat MpfrFloat::operator-(double value) const
544 {
545     MpfrFloat retval(kNoInitialization);
546     mpfr_sub_d(retval.mData->mFloat, mData->mFloat, value, GMP_RNDN);
547     return retval;
548 }
549
550 MpfrFloat MpfrFloat::operator*(const MpfrFloat& rhs) const
551 {
552     MpfrFloat retval(kNoInitialization);
553     mpfr_mul(retval.mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN);
554     return retval;
555 }
556
557 MpfrFloat MpfrFloat::operator*(double value) const
558 {
559     MpfrFloat retval(kNoInitialization);
560     mpfr_mul_d(retval.mData->mFloat, mData->mFloat, value, GMP_RNDN);
561     return retval;
562 }
563
564 MpfrFloat MpfrFloat::operator/(const MpfrFloat& rhs) const
565 {
566     MpfrFloat retval(kNoInitialization);
567     mpfr_div(retval.mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN);
568     return retval;
569 }
570
571 MpfrFloat MpfrFloat::operator/(double value) const
572 {
573     MpfrFloat retval(kNoInitialization);
574     mpfr_div_d(retval.mData->mFloat, mData->mFloat, value, GMP_RNDN);
575     return retval;
576 }
577
578 MpfrFloat MpfrFloat::operator%(const MpfrFloat& rhs) const
579 {
580     MpfrFloat retval(kNoInitialization);
581     mpfr_fmod(retval.mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN);
582     return retval;
583 }
584
585 MpfrFloat MpfrFloat::operator-() const
586 {
587     MpfrFloat retval(kNoInitialization);
588     mpfr_neg(retval.mData->mFloat, mData->mFloat, GMP_RNDN);
589     return retval;
590 }
591
592
593
594 //===========================================================================
595 // Comparison operators
596 //===========================================================================
597 bool MpfrFloat::operator<(const MpfrFloat& rhs) const
598 {
599     return mpfr_cmp(mData->mFloat, rhs.mData->mFloat) < 0;
600 }
601
602 bool MpfrFloat::operator<(double value) const
603 {
604     return mpfr_cmp_d(mData->mFloat, value) < 0;
605 }
606
607 bool MpfrFloat::operator<=(const MpfrFloat& rhs) const
608 {
609     return mpfr_cmp(mData->mFloat, rhs.mData->mFloat) <= 0;
610 }
611
612 bool MpfrFloat::operator<=(double value) const
613 {
614     return mpfr_cmp_d(mData->mFloat, value) <= 0;
615 }
616
617 bool MpfrFloat::operator>(const MpfrFloat& rhs) const
618 {
619     return mpfr_cmp(mData->mFloat, rhs.mData->mFloat) > 0;
620 }
621
622 bool MpfrFloat::operator>(double value) const
623 {
624     return mpfr_cmp_d(mData->mFloat, value) > 0;
625 }
626
627 bool MpfrFloat::operator>=(const MpfrFloat& rhs) const
628 {
629     return mpfr_cmp(mData->mFloat, rhs.mData->mFloat) >= 0;
630 }
631
632 bool MpfrFloat::operator>=(double value) const
633 {
634     return mpfr_cmp_d(mData->mFloat, value) >= 0;
635 }
636
637 bool MpfrFloat::operator==(const MpfrFloat& rhs) const
638 {
639     return mpfr_cmp(mData->mFloat, rhs.mData->mFloat) == 0;
640 }
641
642 bool MpfrFloat::operator==(double value) const
643 {
644     return mpfr_cmp_d(mData->mFloat, value) == 0;
645 }
646
647 bool MpfrFloat::operator!=(const MpfrFloat& rhs) const
648 {
649     return mpfr_cmp(mData->mFloat, rhs.mData->mFloat) != 0;
650 }
651
652 bool MpfrFloat::operator!=(double value) const
653 {
654     return mpfr_cmp_d(mData->mFloat, value) != 0;
655 }
656
657
658 //===========================================================================
659 // Operator functions
660 //===========================================================================
661 MpfrFloat operator+(double lhs, const MpfrFloat& rhs)
662 {
663     MpfrFloat retval(MpfrFloat::kNoInitialization);
664     mpfr_add_d(retval.mData->mFloat, rhs.mData->mFloat, lhs, GMP_RNDN);
665     return retval;
666 }
667
668 MpfrFloat operator-(double lhs, const MpfrFloat& rhs)
669 {
670     MpfrFloat retval(MpfrFloat::kNoInitialization);
671     mpfr_d_sub(retval.mData->mFloat, lhs, rhs.mData->mFloat, GMP_RNDN);
672     return retval;
673 }
674
675 MpfrFloat operator*(double lhs, const MpfrFloat& rhs)
676 {
677     return rhs * lhs;
678 }
679
680 MpfrFloat operator/(double lhs, const MpfrFloat& rhs)
681 {
682     return MpfrFloat(lhs) / rhs;
683 }
684
685 MpfrFloat operator%(double lhs, const MpfrFloat& rhs)
686 {
687     return MpfrFloat(lhs) % rhs;
688 }
689
690 std::ostream& operator<<(std::ostream& os, const MpfrFloat& value)
691 {
692     os << value.getAsString(unsigned(os.precision()));
693     return os;
694 }
695
696 //===========================================================================
697 // Static functions
698 //===========================================================================
699 MpfrFloat MpfrFloat::log(const MpfrFloat& value)
700 {
701     MpfrFloat retval(MpfrFloat::kNoInitialization);
702     mpfr_log(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN);
703     return retval;
704 }
705
706 MpfrFloat MpfrFloat::log2(const MpfrFloat& value)
707 {
708     MpfrFloat retval(MpfrFloat::kNoInitialization);
709     mpfr_log2(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN);
710     return retval;
711 }
712
713 MpfrFloat MpfrFloat::log10(const MpfrFloat& value)
714 {
715     MpfrFloat retval(MpfrFloat::kNoInitialization);
716     mpfr_log10(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN);
717     return retval;
718 }
719
720 MpfrFloat MpfrFloat::exp(const MpfrFloat& value)
721 {
722     MpfrFloat retval(MpfrFloat::kNoInitialization);
723     mpfr_exp(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN);
724     return retval;
725 }
726
727 MpfrFloat MpfrFloat::exp2(const MpfrFloat& value)
728 {
729     MpfrFloat retval(MpfrFloat::kNoInitialization);
730     mpfr_exp2(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN);
731     return retval;
732 }
733
734 MpfrFloat MpfrFloat::exp10(const MpfrFloat& value)
735 {
736     MpfrFloat retval(MpfrFloat::kNoInitialization);
737     mpfr_exp10(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN);
738     return retval;
739 }
740
741 MpfrFloat MpfrFloat::cos(const MpfrFloat& value)
742 {
743     MpfrFloat retval(MpfrFloat::kNoInitialization);
744     mpfr_cos(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN);
745     return retval;
746 }
747
748 MpfrFloat MpfrFloat::sin(const MpfrFloat& value)
749 {
750     MpfrFloat retval(MpfrFloat::kNoInitialization);
751     mpfr_sin(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN);
752     return retval;
753 }
754
755 MpfrFloat MpfrFloat::tan(const MpfrFloat& value)
756 {
757     MpfrFloat retval(MpfrFloat::kNoInitialization);
758     mpfr_tan(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN);
759     return retval;
760 }
761
762 MpfrFloat MpfrFloat::sec(const MpfrFloat& value)
763 {
764     MpfrFloat retval(MpfrFloat::kNoInitialization);
765     mpfr_sec(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN);
766     return retval;
767 }
768
769 MpfrFloat MpfrFloat::csc(const MpfrFloat& value)
770 {
771     MpfrFloat retval(MpfrFloat::kNoInitialization);
772     mpfr_csc(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN);
773     return retval;
774 }
775
776 MpfrFloat MpfrFloat::cot(const MpfrFloat& value)
777 {
778     MpfrFloat retval(MpfrFloat::kNoInitialization);
779     mpfr_cot(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN);
780     return retval;
781 }
782
783 void MpfrFloat::sincos(const MpfrFloat& value,
784                        MpfrFloat& sin,
785                        MpfrFloat& cos)
786 {
787     mpfr_sin_cos(
788         sin.mData->mFloat, cos.mData->mFloat, value.mData->mFloat, GMP_RNDN);
789 }
790
791 MpfrFloat MpfrFloat::acos(const MpfrFloat& value)
792 {
793     MpfrFloat retval(MpfrFloat::kNoInitialization);
794     mpfr_acos(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN);
795     return retval;
796 }
797
798 MpfrFloat MpfrFloat::asin(const MpfrFloat& value)
799 {
800     MpfrFloat retval(MpfrFloat::kNoInitialization);
801     mpfr_asin(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN);
802     return retval;
803 }
804
805 MpfrFloat MpfrFloat::atan(const MpfrFloat& value)
806 {
807     MpfrFloat retval(MpfrFloat::kNoInitialization);
808     mpfr_atan(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN);
809     return retval;
810 }
811
812 MpfrFloat MpfrFloat::atan2(const MpfrFloat& value1, const MpfrFloat& value2)
813 {
814     MpfrFloat retval(MpfrFloat::kNoInitialization);
815     mpfr_atan2(retval.mData->mFloat,
816                value1.mData->mFloat, value2.mData->mFloat, GMP_RNDN);
817     return retval;
818 }
819
820 MpfrFloat MpfrFloat::hypot(const MpfrFloat& value1, const MpfrFloat& value2)
821 {
822     MpfrFloat retval(MpfrFloat::kNoInitialization);
823     mpfr_hypot(retval.mData->mFloat,
824                value1.mData->mFloat, value2.mData->mFloat, GMP_RNDN);
825     return retval;
826 }
827
828 MpfrFloat MpfrFloat::cosh(const MpfrFloat& value)
829 {
830     MpfrFloat retval(MpfrFloat::kNoInitialization);
831     mpfr_cosh(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN);
832     return retval;
833 }
834
835 MpfrFloat MpfrFloat::sinh(const MpfrFloat& value)
836 {
837     MpfrFloat retval(MpfrFloat::kNoInitialization);
838     mpfr_sinh(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN);
839     return retval;
840 }
841
842 MpfrFloat MpfrFloat::tanh(const MpfrFloat& value)
843 {
844     MpfrFloat retval(MpfrFloat::kNoInitialization);
845     mpfr_tanh(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN);
846     return retval;
847 }
848
849 MpfrFloat MpfrFloat::acosh(const MpfrFloat& value)
850 {
851     MpfrFloat retval(MpfrFloat::kNoInitialization);
852     mpfr_acosh(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN);
853     return retval;
854 }
855
856 MpfrFloat MpfrFloat::asinh(const MpfrFloat& value)
857 {
858     MpfrFloat retval(MpfrFloat::kNoInitialization);
859     mpfr_asinh(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN);
860     return retval;
861 }
862
863 MpfrFloat MpfrFloat::atanh(const MpfrFloat& value)
864 {
865     MpfrFloat retval(MpfrFloat::kNoInitialization);
866     mpfr_atanh(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN);
867     return retval;
868 }
869
870 MpfrFloat MpfrFloat::sqrt(const MpfrFloat& value)
871 {
872     MpfrFloat retval(MpfrFloat::kNoInitialization);
873     mpfr_sqrt(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN);
874     return retval;
875 }
876
877 MpfrFloat MpfrFloat::cbrt(const MpfrFloat& value)
878 {
879     MpfrFloat retval(MpfrFloat::kNoInitialization);
880     mpfr_cbrt(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN);
881     return retval;
882 }
883
884 MpfrFloat MpfrFloat::root(const MpfrFloat& value, unsigned long root)
885 {
886     MpfrFloat retval(MpfrFloat::kNoInitialization);
887     mpfr_root(retval.mData->mFloat, value.mData->mFloat, root, GMP_RNDN);
888     return retval;
889 }
890
891 MpfrFloat MpfrFloat::pow(const MpfrFloat& value1, const MpfrFloat& value2)
892 {
893     MpfrFloat retval(MpfrFloat::kNoInitialization);
894     mpfr_pow(retval.mData->mFloat,
895              value1.mData->mFloat, value2.mData->mFloat, GMP_RNDN);
896     return retval;
897 }
898
899 MpfrFloat MpfrFloat::pow(const MpfrFloat& value, long exponent)
900 {
901     MpfrFloat retval(MpfrFloat::kNoInitialization);
902     mpfr_pow_si(retval.mData->mFloat, value.mData->mFloat, exponent, GMP_RNDN);
903     return retval;
904 }
905
906 MpfrFloat MpfrFloat::abs(const MpfrFloat& value)
907 {
908     MpfrFloat retval(MpfrFloat::kNoInitialization);
909     mpfr_abs(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN);
910     return retval;
911 }
912
913 MpfrFloat MpfrFloat::dim(const MpfrFloat& value1, const MpfrFloat& value2)
914 {
915     MpfrFloat retval(MpfrFloat::kNoInitialization);
916     mpfr_dim(retval.mData->mFloat,
917              value1.mData->mFloat, value2.mData->mFloat, GMP_RNDN);
918     return retval;
919 }
920
921 MpfrFloat MpfrFloat::round(const MpfrFloat& value)
922 {
923     MpfrFloat retval(MpfrFloat::kNoInitialization);
924     mpfr_round(retval.mData->mFloat, value.mData->mFloat);
925     return retval;
926 }
927
928 MpfrFloat MpfrFloat::ceil(const MpfrFloat& value)
929 {
930     MpfrFloat retval(MpfrFloat::kNoInitialization);
931     mpfr_ceil(retval.mData->mFloat, value.mData->mFloat);
932     return retval;
933 }
934
935 MpfrFloat MpfrFloat::floor(const MpfrFloat& value)
936 {
937     MpfrFloat retval(MpfrFloat::kNoInitialization);
938     mpfr_floor(retval.mData->mFloat, value.mData->mFloat);
939     return retval;
940 }
941
942 MpfrFloat MpfrFloat::trunc(const MpfrFloat& value)
943 {
944     MpfrFloat retval(MpfrFloat::kNoInitialization);
945     mpfr_trunc(retval.mData->mFloat, value.mData->mFloat);
946     return retval;
947 }
948
949 MpfrFloat MpfrFloat::parseString(const char* str, char** endptr)
950 {
951     MpfrFloat retval(MpfrFloat::kNoInitialization);
952     mpfr_strtofr(retval.mData->mFloat, str, endptr, 0, GMP_RNDN);
953     return retval;
954 }
955
956 MpfrFloat MpfrFloat::const_pi()
957 {
958     return mpfrFloatDataContainer().const_pi();
959 }
960
961 MpfrFloat MpfrFloat::const_e()
962 {
963     return mpfrFloatDataContainer().const_e();
964 }
965
966 MpfrFloat MpfrFloat::const_log2()
967 {
968     return mpfrFloatDataContainer().const_log2();
969 }
970
971 MpfrFloat MpfrFloat::someEpsilon()
972 {
973     return mpfrFloatDataContainer().const_epsilon();
974 }