1/* Test precision of mpf_class expressions.
2
3Copyright 2001-2003, 2008 Free Software Foundation, Inc.
4
5This file is part of the GNU MP Library test suite.
6
7The GNU MP Library test suite is free software; you can redistribute it
8and/or modify it under the terms of the GNU General Public License as
9published by the Free Software Foundation; either version 3 of the License,
10or (at your option) any later version.
11
12The GNU MP Library test suite is distributed in the hope that it will be
13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
15Public License for more details.
16
17You should have received a copy of the GNU General Public License along with
18the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
19
20#include "config.h"
21
22#include <iostream>
23
24#include "gmpxx.h"
25#include "gmp-impl.h"
26#include "tests.h"
27
28using namespace std;
29
30
31const int
32small_prec = 64, medium_prec = 128, large_prec = 192, very_large_prec = 256;
33
34#define ASSERT_ALWAYS_PREC(a, s, prec) \
35{                                      \
36  mpf_srcptr _a = a.get_mpf_t();       \
37  mpf_class _b(s, prec);               \
38  mpf_srcptr _c = _b.get_mpf_t();      \
39  ASSERT_ALWAYS(mpf_eq(_a, _c, prec)); \
40}
41
42
43
44void
45check_mpf (void)
46{
47  mpf_set_default_prec(medium_prec);
48
49  // simple expressions
50  {
51    mpf_class f(3.0, small_prec);
52    mpf_class g(1 / f, very_large_prec);
53    ASSERT_ALWAYS_PREC
54      (g, "0.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333"
55       "     33333 33333 33333 33333 33333 333", very_large_prec);
56  }
57  {
58    mpf_class f(9.0, medium_prec);
59    mpf_class g(0.0, very_large_prec);
60    g = 1 / f;
61    ASSERT_ALWAYS_PREC
62      (g, "0.11111 11111 11111 11111 11111 11111 11111 11111 11111 11111"
63       "     11111 11111 11111 11111 11111 111", very_large_prec);
64  }
65  {
66    mpf_class f(15.0, large_prec);
67    mpf_class g(0.0, very_large_prec);
68    g = 1 / f;
69    ASSERT_ALWAYS_PREC
70      (g, "0.06666 66666 66666 66666 66666 66666 66666 66666 66666 66666"
71       "     66666 66666 66666 66666 66666 667", very_large_prec);
72  }
73
74  // compound expressions
75  {
76    mpf_class f(3.0, small_prec);
77    mpf_class g(-(-(-1 / f)), very_large_prec);
78    ASSERT_ALWAYS_PREC
79      (g, "-0.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333"
80       "      33333 33333 33333 33333 33333 333", very_large_prec);
81  }
82  {
83    mpf_class f(3.0, small_prec), g(9.0, medium_prec);
84    mpf_class h(0.0, very_large_prec);
85    h = 1/f + 1/g;
86    ASSERT_ALWAYS_PREC
87      (h, "0.44444 44444 44444 44444 44444 44444 44444 44444 44444 44444"
88       "     44444 44444 44444 44444 44444 444", very_large_prec);
89  }
90  {
91    mpf_class f(3.0, small_prec), g(9.0, medium_prec), h(15.0, large_prec);
92    mpf_class i(0.0, very_large_prec);
93    i = f / g + h;
94    ASSERT_ALWAYS_PREC
95      (i, "15.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333"
96       "      33333 33333 33333 33333 33333 3", very_large_prec);
97  }
98  {
99    mpf_class f(3.0, small_prec);
100    mpf_class g(-(1 + f) / 3, very_large_prec);
101    ASSERT_ALWAYS_PREC
102      (g, "-1.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333"
103       "      33333 33333 33333 33333 33333 33", very_large_prec);
104  }
105  {
106    mpf_class f(9.0, medium_prec);
107    mpf_class g(0.0, very_large_prec);
108    g = sqrt(1 / f);
109    ASSERT_ALWAYS_PREC
110      (g, "0.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333"
111       "     33333 33333 33333 33333 33333 333", very_large_prec);
112  }
113  {
114    mpf_class f(15.0, large_prec);
115    mpf_class g(0.0, very_large_prec);
116    g = hypot(1 + 5 / f, 1.0);
117    ASSERT_ALWAYS_PREC
118      (g, "1.66666 66666 66666 66666 66666 66666 66666 66666 66666 66666"
119       "     66666 66666 66666 66666 66666 67", very_large_prec);
120  }
121
122  // compound assignments
123  {
124    mpf_class f(3.0, small_prec), g(9.0, medium_prec);
125    mpf_class h(1.0, very_large_prec);
126    h -= f / g;
127    ASSERT_ALWAYS_PREC
128      (h, "0.66666 66666 66666 66666 66666 66666 66666 66666 66666 66666"
129       "     66666 66666 66666 66666 66666 667", very_large_prec);
130  }
131
132  // construction from expressions
133  {
134    mpf_class f(3.0, small_prec);
135    mpf_class g(0.0, very_large_prec);
136    g = mpf_class(1 / f);
137    ASSERT_ALWAYS_PREC(g, "0.33333 33333 33333 33333", small_prec);
138  }
139  {
140    mpf_class f(9.0, medium_prec);
141    mpf_class g(0.0, very_large_prec);
142    g = mpf_class(1 / f);
143    ASSERT_ALWAYS_PREC
144      (g, "0.11111 11111 11111 11111 11111 11111 11111 1111", medium_prec);
145  }
146  {
147    mpf_class f(15.0, large_prec);
148    mpf_class g(0.0, very_large_prec);
149    g = mpf_class(1 / f);
150    ASSERT_ALWAYS_PREC
151      (g, "0.06666 66666 66666 66666 66666 66666 66666 66666 66666 66666"
152       "     66666 6667", large_prec);
153  }
154
155  {
156    mpf_class f(3.0, small_prec), g(9.0, medium_prec);
157    mpf_class h(0.0, very_large_prec);
158    h = mpf_class(f / g + 1, large_prec);
159    ASSERT_ALWAYS_PREC
160      (h, "1.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333"
161       "     33333 333",
162       large_prec);
163  }
164
165  // mixed mpf/mpq expressions
166  {
167    mpf_class f(3.0, small_prec);
168    mpq_class q(1, 3);
169    mpf_class g(0.0, very_large_prec);
170    g = f - q;
171    ASSERT_ALWAYS_PREC
172      (g, "2.66666 66666 66666 66666 66666 66666 66666 66666 66666 66666"
173       "     66666 66666 66666 66666 66666 67", very_large_prec);
174  }
175
176  {
177    mpf_class f(3.0, small_prec);
178    mpq_class q(1, 3);
179    mpf_class g(0.0, very_large_prec);
180    g = mpf_class(f - q, large_prec);
181    ASSERT_ALWAYS_PREC
182      (g, "2.66666 66666 66666 66666 66666 66666 66666 66666 66666 66666"
183       "     66666 667",
184       large_prec);
185  }
186  {
187    mpf_class f(3.0, small_prec);
188    mpq_class q(1, 3);
189    mpf_class g(0.0, very_large_prec);
190    g = mpf_class(f - q);
191    ASSERT_ALWAYS_PREC
192      (g, "2.66666 66666 66666 66666 66666 66666 66666 667", medium_prec);
193  }
194  {
195    mpf_class f(15.0, large_prec);
196    mpq_class q(1, 3);
197    mpf_class g(0.0, very_large_prec);
198    g = mpf_class(f + q);
199    ASSERT_ALWAYS_PREC
200      (g, "15.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333"
201       "      33333 33",
202       large_prec);
203  }
204}
205
206
207int
208main (void)
209{
210  tests_start();
211
212  check_mpf();
213
214  tests_end();
215  return 0;
216}
217