1 /* Test precision of mpf_class expressions.
2 
3 Copyright 2001-2003, 2008 Free Software Foundation, Inc.
4 
5 This file is part of the GNU MP Library test suite.
6 
7 The GNU MP Library test suite is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 3 of the License,
10 or (at your option) any later version.
11 
12 The GNU MP Library test suite is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
15 Public License for more details.
16 
17 You should have received a copy of the GNU General Public License along with
18 the 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 
28 using namespace std;
29 
30 
31 const int
32 small_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 
44 void
check_mpf(void)45 check_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 
207 int
main(void)208 main (void)
209 {
210   tests_start();
211 
212   check_mpf();
213 
214   tests_end();
215   return 0;
216 }
217