4
/// This file is part of Rheolef.
6
/// Copyright (C) 2000-2009 Pierre Saramito <Pierre.Saramito@imag.fr>
8
/// Rheolef is free software; you can redistribute it and/or modify
9
/// it under the terms of the GNU General Public License as published by
10
/// the Free Software Foundation; either version 2 of the License, or
11
/// (at your option) any later version.
13
/// Rheolef is distributed in the hope that it will be useful,
14
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
15
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
/// GNU General Public License for more details.
18
/// You should have received a copy of the GNU General Public License
19
/// along with Rheolef; if not, write to the Free Software
20
/// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
/// =========================================================================
24
// bigfloat<N> class with N digits precision
25
// as a remplacement for the double
28
// class numeric_limits <bigfloat<N> >
29
// class numeric_flags <bigfloat<N> >
31
// author: Pierre.Saramito@imag.fr
33
// date: 25 january 2000
35
// IMPLEMENTATION NOTE:
36
// this is a wrapper class for cln_F:
37
// provides an interface comparable to double.
40
// knows setprecision(n) but
41
// does not respond to
42
// scientific & fixed & uppercase
44
// TODO: complete the math lib, as IEEE
45
// -> see the blitz test suite.
54
#ifdef _RHEOLEF_HAVE_GINAC
55
#include <ginac/ginac.h>
56
#endif // _RHEOLEF_HAVE_GINAC
57
#include "rheolef/numeric_limits.h"
58
#include "rheolef/numeric_flags.h"
59
#include "all_float_io.h"
66
// allocators/deallocators
68
bigfloat(double x = 0);
69
bigfloat(const char* s);
72
bigfloat(unsigned int x);
73
bigfloat(unsigned long x);
77
operator double() const; // compiler do not send any warning, such as
78
operator int() const; // warning: initialization to `int' from `bigfloat' !!
79
#ifdef _RHEOLEF_HAVE_GINAC
80
operator GiNaC::ex() const;
81
#endif // _RHEOLEF_HAVE_GINAC
85
bigfloat<N>& operator = (const bigfloat<N>&);
86
bigfloat<N>& operator = (const char*&);
87
bigfloat<N>& operator = (const double&);
88
bigfloat<N>& operator = (const int&);
89
bigfloat<N>& operator = (const long&);
90
bigfloat<N>& operator = (const unsigned int&);
91
bigfloat<N>& operator = (const unsigned long&);
95
friend bigfloat<M> operator - (const bigfloat<M>&);
97
# define bigfloat_binary_operator_basic(op,T1,T2) \
99
friend bigfloat<M> operator op (const T1&, const T2&);
101
# define bigfloat_binary_operator(op) \
102
bigfloat_binary_operator_basic(op,bigfloat<M>,bigfloat<M>) \
103
bigfloat_binary_operator_basic(op,bigfloat<M>,double) \
104
bigfloat_binary_operator_basic(op,bigfloat<M>,int) \
105
bigfloat_binary_operator_basic(op,bigfloat<M>,long) \
106
bigfloat_binary_operator_basic(op,bigfloat<M>,unsigned int) \
107
bigfloat_binary_operator_basic(op,bigfloat<M>,unsigned long) \
108
bigfloat_binary_operator_basic(op,double,bigfloat<M>) \
109
bigfloat_binary_operator_basic(op,int,bigfloat<M>) \
110
bigfloat_binary_operator_basic(op,long,bigfloat<M>) \
111
bigfloat_binary_operator_basic(op,unsigned int,bigfloat<M>) \
112
bigfloat_binary_operator_basic(op,unsigned long,bigfloat<M>)
114
bigfloat_binary_operator(+)
115
bigfloat_binary_operator(-)
116
bigfloat_binary_operator(*)
117
bigfloat_binary_operator(/)
119
# undef bigfloat_binary_operator_basic
120
# undef bigfloat_binary_operator
122
// computed assignments
124
# define bigfloat_computed_assignment(op) \
125
bigfloat<N>& operator op(const bigfloat<N>&); \
126
bigfloat<N>& operator op(const double&); \
127
bigfloat<N>& operator op(const int&); \
128
bigfloat<N>& operator op(const long&); \
129
bigfloat<N>& operator op(const unsigned int&); \
130
bigfloat<N>& operator op(const unsigned long&);
132
bigfloat_computed_assignment(+=)
133
bigfloat_computed_assignment(-=)
134
bigfloat_computed_assignment(*=)
135
bigfloat_computed_assignment(/=)
137
#undef bigfloat_computed_assignment
141
#define bigfloat_comparator_basic(op) \
143
friend bool operator op (const bigfloat<M>&, const bigfloat<M>&);
144
#define bigfloat_comparator_both(op,T) \
146
friend bool operator op (const bigfloat<M>&, const T&); \
148
friend bool operator op (const T&, const bigfloat<M>&);
149
#define bigfloat_comparator(op) \
150
bigfloat_comparator_basic(op) \
151
bigfloat_comparator_both(op,double) \
152
bigfloat_comparator_both(op,int) \
153
bigfloat_comparator_both(op,long) \
154
bigfloat_comparator_both(op,unsigned int) \
155
bigfloat_comparator_both(op,unsigned long)
157
bigfloat_comparator(==)
158
bigfloat_comparator(!=)
159
bigfloat_comparator(<)
160
bigfloat_comparator(>)
161
bigfloat_comparator(<=)
162
bigfloat_comparator(>=)
164
#undef bigfloat_comparator
165
#undef bigfloat_comparator_basic
166
#undef bigfloat_comparator_both
170
template <int M> friend bigfloat<M> fabs(const bigfloat<M>& x);
171
template <int M> friend bigfloat<M> sqrt(const bigfloat<M>& x);
172
template <int M> friend bigfloat<M> sin(const bigfloat<M>& x);
173
template <int M> friend bigfloat<M> cos(const bigfloat<M>& x);
174
template <int M> friend bigfloat<M> tan(const bigfloat<M>& x);
175
template <int M> friend bigfloat<M> log(const bigfloat<M>& x);
176
template <int M> friend bigfloat<M> exp(const bigfloat<M>& x);
177
template <int M> friend bigfloat<M> sinh(const bigfloat<M>& x);
178
template <int M> friend bigfloat<M> cosh(const bigfloat<M>& x);
179
template <int M> friend bigfloat<M> tanh(const bigfloat<M>& x);
180
template <int M> friend bigfloat<M> atan(const bigfloat<M>& x);
181
template <int M> friend bigfloat<M> acos(const bigfloat<M>& x);
182
template <int M> friend bigfloat<M> sqr(const bigfloat<M>& x);
183
template <int M> friend bigfloat<M> floor(const bigfloat<M>& x);
184
template <int M> friend bigfloat<M> ceil(const bigfloat<M>& x);
185
template <int M> friend bigfloat<M> trunc(const bigfloat<M>& x);
186
template <int M> friend bigfloat<M> round(const bigfloat<M>& x);
188
template <int M> friend bigfloat<M> log10(const bigfloat<M>& x);
189
template <int M> friend bigfloat<M> pow(const bigfloat<M>& x, const bigfloat<M>& y);
190
template <int M> friend bigfloat<M> pow(const bigfloat<M>& x, int n);
194
template <int M> friend std::ostream& operator << (std::ostream& s, const bigfloat<M>& x);
195
template <int M> friend std::istream& operator >> (std::istream& s, bigfloat<M>& x);
197
// constants (may be const! -> core dump..)
200
static bigfloat<N> Pi;
201
static bigfloat<N> one_on_log10;
206
// Returns the smallest float format which guarantees at least
207
// n decimal digits in the mantissa (after the decimal point).
208
// Methode from: cln-1.0.2/src/float/misc/cl_float_format.cc
209
// Mindestens 1+n Dezimalstellen (inklusive Vorkommastelle)
210
// bedeutet mindestens ceiling((1+n)*ln(10)/ln(2)) Binļæ½rstellen.
211
// ln(10)/ln(2) = 3.321928095 = (binļæ½r) 11.01010010011010011110000100101111...
212
// = (binļæ½r) 100 - 0.10101101100101100001111011010001
213
// Durch diese Berechnungsmethode wird das Ergebnis sicher >= (1+n)*ln(10)/ln(2)
214
// sein, evtl. um ein paar Bit zu groļæ½, aber nicht zu klein.
216
static const int digits
218
- ((1+N) >> 1) - ((1+N) >> 3) - ((1+N) >> 5)
219
- ((1+N) >> 6) - ((1+N) >> 8) - ((1+N) >> 9)
220
- ((1+N) >> 12) - ((1+N) >> 14) - ((1+N) >> 15);
222
static const int digits10 = N;
224
static bigfloat<N> epsilon();
225
static bigfloat<N> min();
226
static bigfloat<N> max();
228
// computation of some constants
230
static bigfloat<N> compute_pi();
238
// internal constructor
239
bigfloat(const cln::cl_F& y) : _f(y) {}
243
std::ostream& dump(std::ostream&);
246
// TODO: complete the fields...
250
class numeric_limits <bigfloat<N> > {
252
static const int digits = bigfloat<N>::digits;
253
static const int digits10 = bigfloat<N>::digits10;
255
// have no representation...
256
static bigfloat<N> min () { return bigfloat<N>::min(); }
257
static bigfloat<N> max () { return bigfloat<N>::max(); }
259
static bigfloat<N> epsilon () { return bigfloat<N>::epsilon(); }
260
static bigfloat<N> denorm_min () { return bigfloat<N>::min(); }
262
// CLN does not implement features like NaNs, denormalized numbers
263
// and gradual underflow.
264
// If the exponent range of some floating-point type is too limited
265
// for your application, choose another floating-point type with
266
// larger exponent range.
269
static const int min_exponent = INT_MIN;
270
static const int max_exponent = INT_MAX;
271
static const int min_exponent10 = INT_MIN;
272
static const int max_exponent10 = INT_MAX;
274
__NUMERIC_LIMITS_FLOAT(<bigfloat<N>)
280
class numeric_flags<bigfloat<N> > {
282
static bool output_as_double() { return _output_as_double; }
283
static void output_as_double(bool f) { _output_as_double = f; }
285
static bool _output_as_double;
288
// flag initialisation
291
bool numeric_flags<bigfloat<N> >::_output_as_double = false;
301
return bigfloat<N>(most_negative_float(cln::float_format_t(digits)));
308
return bigfloat<N>(most_positive_float(cln::float_format_t(digits)));
313
bigfloat<N>::epsilon()
315
return bigfloat<N>(float_epsilon(cln::float_format_t(digits)));
323
bigfloat<N>::compute_pi()
325
return bigfloat<N>(cln::pi(cln::float_format_t(digits)));
328
// allocators/deallocators
330
#define bigfloat_cstor(T) \
333
bigfloat<N>::bigfloat(T x) \
334
: _f(cln::cl_float(x, cln::float_format_t(digits))) \
337
bigfloat_cstor(double)
339
bigfloat_cstor(unsigned int)
340
#undef bigfloat_cstor
344
bigfloat<N>::bigfloat(const char* s)
345
: _f(cln::cl_float(cln::cl_F(s), cln::float_format_t(digits)))
353
bigfloat<N>::operator double() const
355
return cln::double_approx(_f);
359
bigfloat<N>::operator int() const
361
return int(double(*this));
363
#ifdef _RHEOLEF_HAVE_GINAC
366
bigfloat<N>::operator GiNaC::ex() const
369
s << std::setprecision(N) << *this;
370
// std::string sx = s.str();
375
#endif // _RHEOLEF_HAVE_GINAC
382
bigfloat<N>::operator = (const bigfloat<N>& x)
387
#define bigfloat_assignment(T) \
391
bigfloat<N>::operator = (const T& x) \
393
_f = cln::cl_float(x, cln::float_format_t(digits)); \
396
bigfloat_assignment(double)
397
bigfloat_assignment(int)
398
bigfloat_assignment(unsigned int)
399
#undef bigfloat_assignment
404
bigfloat<N>::operator = (const char*& x)
406
_f = cln::cl_float(cln::cl_F(x), cln::float_format_t(digits));
415
operator - (const bigfloat<N>& x)
417
return bigfloat<N>(-x._f);
420
# define bigfloat_binary_operator_basic(op) \
424
operator op (const bigfloat<N>& x, const bigfloat<N>& y) \
426
return bigfloat<N>(x._f op y._f); \
428
# define bigfloat_binary_operator_left(op,T1) \
432
operator op (const T1& x, const bigfloat<N>& y) \
434
return bigfloat<N>(x) op y; \
436
# define bigfloat_binary_operator_right(op,T2) \
440
operator op (const bigfloat<N>& x, const T2& y) \
442
return x op bigfloat<N>(y); \
444
# define bigfloat_binary_operator_both(op,T) \
445
bigfloat_binary_operator_left(op,T) \
446
bigfloat_binary_operator_right(op,T)
448
# define bigfloat_binary_operator(op) \
449
bigfloat_binary_operator_basic(op) \
450
bigfloat_binary_operator_both(op,double) \
451
bigfloat_binary_operator_both(op,int) \
452
bigfloat_binary_operator_both(op,long) \
453
bigfloat_binary_operator_both(op,unsigned int) \
454
bigfloat_binary_operator_both(op,unsigned long)
456
bigfloat_binary_operator(+)
457
bigfloat_binary_operator(-)
458
bigfloat_binary_operator(*)
459
bigfloat_binary_operator(/)
461
# undef bigfloat_binary_operator_basic
462
# undef bigfloat_binary_operator
464
// computed assignments
466
# define bigfloat_computed_assignment_basic(op,T) \
470
bigfloat<N>::operator op##= (const T& x) \
472
(*this) = (*this) op x; \
475
# define bigfloat_computed_assignment(op) \
476
bigfloat_computed_assignment_basic(op,bigfloat<N>) \
477
bigfloat_computed_assignment_basic(op,double) \
478
bigfloat_computed_assignment_basic(op,int) \
479
bigfloat_computed_assignment_basic(op,long) \
480
bigfloat_computed_assignment_basic(op,unsigned int) \
481
bigfloat_computed_assignment_basic(op,unsigned long)
483
bigfloat_computed_assignment(+)
484
bigfloat_computed_assignment(-)
485
bigfloat_computed_assignment(*)
486
bigfloat_computed_assignment(/)
488
# undef bigfloat_computed_assignment_basic
489
# undef bigfloat_computed_assignment
493
#define bigfloat_comparator_basic(op) \
497
operator op (const bigfloat<N>& x, const bigfloat<N>& y) \
499
return (cln::compare(x._f,y._f) op 0); \
501
#define bigfloat_comparator_both(op,T) \
505
operator op (const bigfloat<N>& x, const T& y) \
507
return (x op bigfloat<N>(y)); \
512
operator op (const T& x, const bigfloat<N>& y) \
514
return (bigfloat<N>(x) op y); \
516
#define bigfloat_comparator(op) \
517
bigfloat_comparator_basic(op) \
518
bigfloat_comparator_both(op,double) \
519
bigfloat_comparator_both(op,int) \
520
bigfloat_comparator_both(op,long) \
521
bigfloat_comparator_both(op,unsigned int) \
522
bigfloat_comparator_both(op,unsigned long)
524
bigfloat_comparator(==) \
525
bigfloat_comparator(!=) \
526
bigfloat_comparator(<) \
527
bigfloat_comparator(>) \
528
bigfloat_comparator(<=) \
529
bigfloat_comparator(>=)
531
#undef bigfloat_comparator_basic
532
#undef bigfloat_comparator_both
533
#undef bigfloat_comparator
538
doubledouble hypot(const doubledouble, const doubledouble);
539
doubledouble cub(const doubledouble&);
540
doubledouble rint(const doubledouble&);
541
doubledouble fmod(const doubledouble&, const int);
542
doubledouble modf(const doubledouble&, doubledouble *ip);
543
void sincos(const doubledouble x, doubledouble& sinx, doubledouble& cosx);
544
doubledouble atan2(const doubledouble&, const doubledouble&);
545
doubledouble asin(const doubledouble&);
546
doubledouble erf(const doubledouble);
547
doubledouble erfc(const doubledouble);
548
doubledouble gamma(const doubledouble);
549
int digits(const doubledouble&,const doubledouble&);
550
doubledouble modr(const doubledouble a, const doubledouble b, int& n, doubledouble& rem);
553
#define bigfloat_math_function(fct, cln_fct) \
557
fct (const bigfloat<N>& x) \
559
return cln_fct (x._f); \
561
bigfloat_math_function(fabs, abs)
562
bigfloat_math_function(sqrt, sqrt)
563
bigfloat_math_function(sin, sin)
564
bigfloat_math_function(cos, cos)
565
bigfloat_math_function(tan, tan)
566
bigfloat_math_function(log, ln)
567
bigfloat_math_function(exp, exp)
568
bigfloat_math_function(sinh, sinh)
569
bigfloat_math_function(cosh, cosh)
570
bigfloat_math_function(tanh, tanh)
571
bigfloat_math_function(atan, atan)
572
bigfloat_math_function(sqr, square)
573
bigfloat_math_function(floor, ffloor)
574
bigfloat_math_function(ceil, fceiling)
575
bigfloat_math_function(trunc, ftruncate)
576
bigfloat_math_function(round, fround)
577
#undef bigfloat_math_function
582
log10 (const bigfloat<N>& x)
585
// How to store one_on_log10 one time for all ?
586
return log(x) * bigfloat<N>::one_on_log10;
588
return log(x) / log(bigfloat<N>(10));
594
pow (const bigfloat<N>& x, const bigfloat<N>& y)
597
return pow (x, int(y));
599
if (x == bigfloat<N>(0)) return bigfloat<N>(1);
600
if (x < bigfloat<N>(0)) {
601
fatal_macro ("argument x="<<x<<" of pow(x,y) may be >= 0");
603
return exp(y*log(x));
608
pow (const bigfloat<N>& x, int n)
610
if (x == bigfloat<N>(0)) {
611
if (n == 0) return bigfloat<N>(1);
612
if (n < 0) return bigfloat<N>(1) / bigfloat<N>(0);
613
else return bigfloat<N>(0);
615
if (x < bigfloat<N>(0)) {
617
return - exp(n*log(-x));
619
return exp(n*log(-x));
622
return exp(n*log(x));
627
acos (const bigfloat<N>& x)
629
return bigfloat<N>(cln::cl_float(cln::realpart(acos(x._f))));
637
operator >> (std::istream& s, bigfloat<N>& x)
639
return all_float_read (s, x);
643
operator << (std::ostream& s, const bigfloat<N>& x)
645
return all_float_write (s, x);
651
bigfloat<N>::dump(std::ostream& s)