change support python version
[platform/upstream/boost.git] / libs / multiprecision / test / test_mpfr_mpc_precisions.cpp
1 ///////////////////////////////////////////////////////////////
2 //  Copyright Christopher Kormanyos 2002 - 2011.
3 //  Copyright 2011 John Maddock. Distributed under the Boost
4 //  Software License, Version 1.0. (See accompanying file
5 //  LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
6 //
7 // This work is based on an earlier work:
8 // "Algorithm 910: A Portable C++ Multiple-Precision System for Special-Function Calculations",
9 // in ACM TOMS, {VOL 37, ISSUE 4, (February 2011)} (C) ACM, 2011. http://doi.acm.org/10.1145/1916461.1916469
10
11 #ifdef _MSC_VER
12 #  define _SCL_SECURE_NO_WARNINGS
13 #endif
14
15 #include <boost/detail/lightweight_test.hpp>
16 #include "test.hpp"
17
18 #include <boost/multiprecision/mpfr.hpp>
19 #include <boost/multiprecision/mpc.hpp>
20
21 template <class T>
22 T make_rvalue_copy(const T a)
23 {
24    return a;
25 }
26
27 int main()
28 {
29    using namespace boost::multiprecision;
30    //
31    // Test change of default precision:
32    //
33    mpfr_float::default_precision(100);
34    mpfr_float a("0.1");
35    BOOST_CHECK_EQUAL(a.precision(), 100);
36    mpfr_float::default_precision(20);
37    {
38       // test assignment from lvalue:
39       mpfr_float b(2);
40       BOOST_CHECK_EQUAL(b.precision(), 20);
41       b = a;
42       BOOST_CHECK_EQUAL(b.precision(), a.precision());
43    }
44 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
45    {
46       // test assignment from rvalue:
47       mpfr_float b(2);
48       BOOST_CHECK_EQUAL(b.precision(), 20);
49       b = make_rvalue_copy(a);
50       BOOST_CHECK_EQUAL(b.precision(), a.precision());
51    }
52 #endif
53    mpfr_float::default_precision(20);
54    {
55       // test construct from lvalue:
56       mpfr_float b(a);
57       BOOST_CHECK_EQUAL(b.precision(), 100);
58    }
59 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
60    {
61       // test construct from rvalue:
62       mpfr_float b(make_rvalue_copy(a));
63       BOOST_CHECK_EQUAL(b.precision(), 100);
64    }
65 #endif
66    mpc_complex::default_precision(100);
67    mpc_complex ca("0.1");
68    BOOST_CHECK_EQUAL(ca.precision(), 100);
69    mpc_complex::default_precision(20);
70    {
71       // test assignment from lvalue:
72       mpc_complex b(2);
73       BOOST_CHECK_EQUAL(b.precision(), 20);
74       b = ca;
75       BOOST_CHECK_EQUAL(b.precision(), ca.precision());
76    }
77 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
78    {
79       // test assignment from rvalue:
80       mpc_complex b(2);
81       BOOST_CHECK_EQUAL(b.precision(), 20);
82       b = make_rvalue_copy(ca);
83       BOOST_CHECK_EQUAL(b.precision(), ca.precision());
84    }
85 #endif
86    {
87       // test construct from lvalue:
88       mpc_complex b(ca);
89       BOOST_CHECK_EQUAL(b.precision(), ca.precision());
90    }
91 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
92    {
93       // test construct from rvalue:
94       mpc_complex b(make_rvalue_copy(ca));
95       BOOST_CHECK_EQUAL(b.precision(), ca.precision());
96    }
97 #endif
98    // real and imaginary:
99    BOOST_CHECK_EQUAL(ca.real().precision(), 100);
100    BOOST_CHECK_EQUAL(ca.imag().precision(), 100);
101    BOOST_CHECK_EQUAL(real(ca).precision(), 100);
102    BOOST_CHECK_EQUAL(imag(ca).precision(), 100);
103
104    //
105    // Construction at specific precision:
106    //
107    {
108       mpfr_float f150(mpfr_float(), 150u);
109       BOOST_CHECK_EQUAL(f150.precision(), 150);
110       mpc_complex f150c(mpc_complex(), 150u);
111       BOOST_CHECK_EQUAL(f150c.precision(), 150);
112       mpc_complex f150cc(mpfr_float(), mpfr_float(), 150u);
113       BOOST_CHECK_EQUAL(f150cc.precision(), 150);
114    }
115    {
116       mpfr_float f150(2, 150);
117       BOOST_CHECK_EQUAL(f150.precision(), 150);
118    }
119    {
120       mpfr_float f150("1.2", 150);
121       BOOST_CHECK_EQUAL(f150.precision(), 150);
122    }
123    //
124    // Copying precision:
125    //
126    {
127       mpc_complex c(ca.backend().data());
128       BOOST_CHECK_EQUAL(c.precision(), 100);
129       mpc_complex_100 c100(2);
130       mpc_complex d(c100);
131       BOOST_CHECK_EQUAL(d.precision(), 100);
132       mpfr_float_100 f100(2);
133       mpc_complex e(f100);
134       BOOST_CHECK_EQUAL(d.precision(), 100);
135    }
136    //
137    // Check that the overloads for precision don't mess up 2-arg
138    // construction:
139    //
140    {
141       mpc_complex c(2, 3u);
142       BOOST_CHECK_EQUAL(c.real(), 2);
143       BOOST_CHECK_EQUAL(c.imag(), 3);
144    }
145    //
146    // 3-arg complex number construction with 3rd arg a precision:
147    //
148    {
149       mpc_complex c(2, 3, 100);
150       BOOST_CHECK_EQUAL(c.precision(), 100);
151       mpfr_float_50 x(2), y(3);
152       mpc_complex z(x, y, 100);
153       BOOST_CHECK_EQUAL(c.precision(), 100);
154    }
155    //
156    // From https://github.com/boostorg/multiprecision/issues/65
157    //
158    {
159       mpfr_float a(2);
160       a.precision(100);
161       BOOST_CHECK_EQUAL(a, 2);
162       BOOST_CHECK_EQUAL(a.precision(), 100);
163    }
164    {
165       mpc_complex a(2, 3);
166       a.precision(100);
167       BOOST_CHECK_EQUAL(a.real(), 2);
168       BOOST_CHECK_EQUAL(a.imag(), 3);
169       BOOST_CHECK_EQUAL(a.precision(), 100);
170    }
171    {
172       mpc_complex::default_precision(1000);
173       mpfr_float::default_precision(1000);
174       mpc_complex a("1.324719827394086120398419082734980126734089612309871092830981236748901273498071240986123094861246981263481263489016238947147129807419028748901273409127349087124612576129076541203975704195690418570914657910465091256016501650916509165097164509164509761409561097561097650791650971465097165097162059761209561029756019265019726509126509172650971625097162450971309756104975610274650917825018740981274098127409182375701465172340923847120836540491320467127043127893281461230951097260126309812374091265091824981231236409851274",
175          "-0.80743891267394610982659071452346156102764312401571972642394120395608291471029347812645125986123123904123471209381289471230512983491286102875870192091283712396550981723409812740981263471230498715096104897123094710923879065981740928740981271801391209238470129560941870129387409812883437894183883841283700483832883218128438938184289148239164079329657861209381892037483468937489237419236509823723705612893489712412306531274812364980127304981648712483248732");
176       mpc_complex::default_precision(40);
177       mpfr_float::default_precision(40);
178       BOOST_CHECK_EQUAL(a, a);
179    }
180
181
182    //
183    // string_view with explicit precision:
184    //
185 #ifndef BOOST_NO_CXX17_HDR_STRING_VIEW
186    {
187       std::string s("222");
188       std::string_view v(s.c_str(), 1);
189       mpfr_float f(v, 100);
190       BOOST_CHECK_EQUAL(f, 2);
191       BOOST_CHECK_EQUAL(f.precision(), 100);
192    }
193    {
194       std::string x("222"), y("333");
195       std::string_view vx(x.c_str(), 1), vy(y.c_str(), 1);
196       mpc_complex c(vx, vy, 100);
197       BOOST_CHECK_EQUAL(c.real(), 2);
198       BOOST_CHECK_EQUAL(c.imag(), 3);
199       BOOST_CHECK_EQUAL(c.precision(), 100);
200    }
201 #endif
202    {
203       mpc_complex::default_precision(100);
204       mpfr_float::default_precision(100);
205       mpfr_float a(1);
206       mpfr_float b(2);
207
208       mpc_complex::default_precision(50);
209       mpfr_float::default_precision(50);
210
211       mpc_complex z(a, b);
212
213       BOOST_CHECK_EQUAL(z.precision(), 100);
214    }
215    // Swap:
216    {
217       mpfr_float x(2, 100);  // 100 digits precision.
218       mpfr_float y(3, 50);   // 50 digits precision.
219       swap(x, y);
220       BOOST_CHECK_EQUAL(x, 3);
221       BOOST_CHECK_EQUAL(y, 2);
222       BOOST_CHECK_EQUAL(x.precision(), 50);
223       BOOST_CHECK_EQUAL(y.precision(), 100);
224       x.swap(y);
225       BOOST_CHECK_EQUAL(x, 2);
226       BOOST_CHECK_EQUAL(y, 3);
227       BOOST_CHECK_EQUAL(x.precision(), 100);
228       BOOST_CHECK_EQUAL(y.precision(), 50);
229 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
230       x = std::move(mpfr_float(y));
231       BOOST_CHECK_EQUAL(x, y);
232       BOOST_CHECK_EQUAL(x.precision(), y.precision());
233 #endif
234    }
235    {
236       mpc_complex x(2, 3, 100);  // 100 digits precision.
237       mpc_complex y(3, 4, 50);   // 50 digits precision.
238       swap(x, y);
239       BOOST_CHECK_EQUAL(x.real(), 3);
240       BOOST_CHECK_EQUAL(x.imag(), 4);
241       BOOST_CHECK_EQUAL(y.real(), 2);
242       BOOST_CHECK_EQUAL(y.imag(), 3);
243       BOOST_CHECK_EQUAL(x.precision(), 50);
244       BOOST_CHECK_EQUAL(y.precision(), 100);
245       x.swap(y);
246       BOOST_CHECK_EQUAL(x.real(), 2);
247       BOOST_CHECK_EQUAL(x.imag(), 3);
248       BOOST_CHECK_EQUAL(y.real(), 3);
249       BOOST_CHECK_EQUAL(y.imag(), 4);
250       BOOST_CHECK_EQUAL(x.precision(), 100);
251       BOOST_CHECK_EQUAL(y.precision(), 50);
252 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
253       x = std::move(mpc_complex(y));
254       BOOST_CHECK_EQUAL(x, y);
255       BOOST_CHECK_EQUAL(x.precision(), y.precision());
256 #endif
257    }
258    {
259       mpfr_float c(4), d(8), e(9), f;
260       f = (c + d) * d / e;
261       mpfr_float g((c + d) * d / e);
262    }
263    {
264       mpfr_float::default_precision(100);
265       mpfr_float f1;
266       f1 = 3;
267       BOOST_CHECK_EQUAL(f1.precision(), 100);
268       f1 = 3.5;
269       BOOST_CHECK_EQUAL(f1.precision(), 100);
270       mpfr_float f2(3.5);
271       BOOST_CHECK_EQUAL(f2.precision(), 100);
272       mpfr_float f3("5.1");
273       BOOST_CHECK_EQUAL(f3.precision(), 100);
274
275       mpfr_float::default_precision(50);
276       mpfr_float f4(f3, 50);
277       BOOST_CHECK_EQUAL(f4.precision(), 50);
278       f4.assign(f1, f4.precision());
279       BOOST_CHECK_EQUAL(f4.precision(), 50);
280    }
281    {
282       //
283       // Overloads of Math lib functions, discovered while fixing
284       // https://github.com/boostorg/multiprecision/issues/91
285       //
286       mpfr_float::default_precision(100);
287       mpfr_float f1;
288       f1 = 3;
289       BOOST_CHECK_EQUAL(f1.precision(), 100);
290       mpfr_float::default_precision(20);
291       BOOST_CHECK_EQUAL(asinh(f1).precision(), 100);
292       BOOST_CHECK_EQUAL(acosh(f1).precision(), 100);
293       BOOST_CHECK_EQUAL(atanh(f1).precision(), 100);
294       BOOST_CHECK_EQUAL(cbrt(f1).precision(), 100);
295       BOOST_CHECK_EQUAL(erf(f1).precision(), 100);
296       BOOST_CHECK_EQUAL(erfc(f1).precision(), 100);
297       BOOST_CHECK_EQUAL(expm1(f1).precision(), 100);
298       BOOST_CHECK_EQUAL(lgamma(f1).precision(), 100);
299       BOOST_CHECK_EQUAL(tgamma(f1).precision(), 100);
300       BOOST_CHECK_EQUAL(log1p(f1).precision(), 100);
301    }
302
303    return boost::report_errors();
304 }
305