xref: /netbsd-src/external/lgpl3/gmp/dist/tests/cxx/t-prec.cc (revision d90047b5d07facf36e6c01dcc0bded8997ce9cc2)
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 "gmp.h"
25 #include "gmpxx.h"
26 #include "gmp-impl.h"
27 #include "tests.h"
28 
29 using namespace std;
30 
31 
32 const int
33 small_prec = 64, medium_prec = 128, large_prec = 192, very_large_prec = 256;
34 
35 #define ASSERT_ALWAYS_PREC(a, s, prec) \
36 {                                      \
37   mpf_srcptr _a = a.get_mpf_t();       \
38   mpf_class _b(s, prec);               \
39   mpf_srcptr _c = _b.get_mpf_t();      \
40   ASSERT_ALWAYS(mpf_eq(_a, _c, prec)); \
41 }
42 
43 
44 
45 void
46 check_mpf (void)
47 {
48   mpf_set_default_prec(medium_prec);
49 
50   // simple expressions
51   {
52     mpf_class f(3.0, small_prec);
53     mpf_class g(1 / f, very_large_prec);
54     ASSERT_ALWAYS_PREC
55       (g, "0.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333"
56        "     33333 33333 33333 33333 33333 333", very_large_prec);
57   }
58   {
59     mpf_class f(9.0, medium_prec);
60     mpf_class g(0.0, very_large_prec);
61     g = 1 / f;
62     ASSERT_ALWAYS_PREC
63       (g, "0.11111 11111 11111 11111 11111 11111 11111 11111 11111 11111"
64        "     11111 11111 11111 11111 11111 111", very_large_prec);
65   }
66   {
67     mpf_class f(15.0, large_prec);
68     mpf_class g(0.0, very_large_prec);
69     g = 1 / f;
70     ASSERT_ALWAYS_PREC
71       (g, "0.06666 66666 66666 66666 66666 66666 66666 66666 66666 66666"
72        "     66666 66666 66666 66666 66666 667", very_large_prec);
73   }
74 
75   // compound expressions
76   {
77     mpf_class f(3.0, small_prec);
78     mpf_class g(-(-(-1 / f)), very_large_prec);
79     ASSERT_ALWAYS_PREC
80       (g, "-0.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333"
81        "      33333 33333 33333 33333 33333 333", very_large_prec);
82   }
83   {
84     mpf_class f(3.0, small_prec), g(9.0, medium_prec);
85     mpf_class h(0.0, very_large_prec);
86     h = 1/f + 1/g;
87     ASSERT_ALWAYS_PREC
88       (h, "0.44444 44444 44444 44444 44444 44444 44444 44444 44444 44444"
89        "     44444 44444 44444 44444 44444 444", very_large_prec);
90   }
91   {
92     mpf_class f(3.0, small_prec), g(9.0, medium_prec), h(15.0, large_prec);
93     mpf_class i(0.0, very_large_prec);
94     i = f / g + h;
95     ASSERT_ALWAYS_PREC
96       (i, "15.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333"
97        "      33333 33333 33333 33333 33333 3", very_large_prec);
98   }
99   {
100     mpf_class f(3.0, small_prec);
101     mpf_class g(-(1 + f) / 3, very_large_prec);
102     ASSERT_ALWAYS_PREC
103       (g, "-1.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333"
104        "      33333 33333 33333 33333 33333 33", very_large_prec);
105   }
106   {
107     mpf_class f(9.0, medium_prec);
108     mpf_class g(0.0, very_large_prec);
109     g = sqrt(1 / f);
110     ASSERT_ALWAYS_PREC
111       (g, "0.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333"
112        "     33333 33333 33333 33333 33333 333", very_large_prec);
113   }
114   {
115     mpf_class f(15.0, large_prec);
116     mpf_class g(0.0, very_large_prec);
117     g = hypot(1 + 5 / f, 1.0);
118     ASSERT_ALWAYS_PREC
119       (g, "1.66666 66666 66666 66666 66666 66666 66666 66666 66666 66666"
120        "     66666 66666 66666 66666 66666 67", very_large_prec);
121   }
122 
123   // compound assignments
124   {
125     mpf_class f(3.0, small_prec), g(9.0, medium_prec);
126     mpf_class h(1.0, very_large_prec);
127     h -= f / g;
128     ASSERT_ALWAYS_PREC
129       (h, "0.66666 66666 66666 66666 66666 66666 66666 66666 66666 66666"
130        "     66666 66666 66666 66666 66666 667", very_large_prec);
131   }
132 
133   // construction from expressions
134   {
135     mpf_class f(3.0, small_prec);
136     mpf_class g(0.0, very_large_prec);
137     g = mpf_class(1 / f);
138     ASSERT_ALWAYS_PREC(g, "0.33333 33333 33333 33333", small_prec);
139   }
140   {
141     mpf_class f(9.0, medium_prec);
142     mpf_class g(0.0, very_large_prec);
143     g = mpf_class(1 / f);
144     ASSERT_ALWAYS_PREC
145       (g, "0.11111 11111 11111 11111 11111 11111 11111 1111", medium_prec);
146   }
147   {
148     mpf_class f(15.0, large_prec);
149     mpf_class g(0.0, very_large_prec);
150     g = mpf_class(1 / f);
151     ASSERT_ALWAYS_PREC
152       (g, "0.06666 66666 66666 66666 66666 66666 66666 66666 66666 66666"
153        "     66666 6667", large_prec);
154   }
155 
156   {
157     mpf_class f(3.0, small_prec), g(9.0, medium_prec);
158     mpf_class h(0.0, very_large_prec);
159     h = mpf_class(f / g + 1, large_prec);
160     ASSERT_ALWAYS_PREC
161       (h, "1.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333"
162        "     33333 333",
163        large_prec);
164   }
165 
166   // mixed mpf/mpq expressions
167   {
168     mpf_class f(3.0, small_prec);
169     mpq_class q(1, 3);
170     mpf_class g(0.0, very_large_prec);
171     g = f - q;
172     ASSERT_ALWAYS_PREC
173       (g, "2.66666 66666 66666 66666 66666 66666 66666 66666 66666 66666"
174        "     66666 66666 66666 66666 66666 67", very_large_prec);
175   }
176 
177   {
178     mpf_class f(3.0, small_prec);
179     mpq_class q(1, 3);
180     mpf_class g(0.0, very_large_prec);
181     g = mpf_class(f - q, large_prec);
182     ASSERT_ALWAYS_PREC
183       (g, "2.66666 66666 66666 66666 66666 66666 66666 66666 66666 66666"
184        "     66666 667",
185        large_prec);
186   }
187   {
188     mpf_class f(3.0, small_prec);
189     mpq_class q(1, 3);
190     mpf_class g(0.0, very_large_prec);
191     g = mpf_class(f - q);
192     ASSERT_ALWAYS_PREC
193       (g, "2.66666 66666 66666 66666 66666 66666 66666 667", medium_prec);
194   }
195   {
196     mpf_class f(15.0, large_prec);
197     mpq_class q(1, 3);
198     mpf_class g(0.0, very_large_prec);
199     g = mpf_class(f + q);
200     ASSERT_ALWAYS_PREC
201       (g, "15.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333"
202        "      33333 33",
203        large_prec);
204   }
205 }
206 
207 
208 int
209 main (void)
210 {
211   tests_start();
212 
213   check_mpf();
214 
215   tests_end();
216   return 0;
217 }
218