Upload Tizen:Base source
[external/gmp.git] / tests / cxx / t-ostream.cc
1 /* Test ostream formatted output.
2
3 Copyright 2001, 2002 Free Software Foundation, Inc.
4
5 This file is part of the GNU MP Library.
6
7 The GNU MP Library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11
12 The GNU MP Library is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15 License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
19
20 #include <iostream>
21 #include <cstdlib>
22
23 #include "gmp.h"
24 #include "gmp-impl.h"
25 #include "tests.h"
26
27 using namespace std;
28
29
30 int   option_check_standard = 0;
31
32
33 #define CALL(expr)                                                      \
34   do {                                                                  \
35     got.flags (data[i].flags);                                          \
36     got.width (data[i].width);                                          \
37     got.precision (data[i].precision);                                  \
38     if (data[i].fill == '\0')                                           \
39       got.fill (' ');                                                   \
40     else                                                                \
41       got.fill (data[i].fill);                                          \
42                                                                         \
43     if (! (expr))                                                       \
44       {                                                                 \
45         cout << "\"got\" output error\n";                               \
46         abort ();                                                       \
47       }                                                                 \
48     if (got.width() != 0)                                               \
49       {                                                                 \
50         cout << "\"got\" width not reset to 0\n";                       \
51         abort ();                                                       \
52       }                                                                 \
53                                                                         \
54   } while (0)
55
56
57 #define DUMP()                                                          \
58   do {                                                                  \
59     cout << "  want:  |" << data[i].want << "|\n";                      \
60     cout << "  got:   |" << got.str() << "|\n";                         \
61     cout << "  width: " << data[i].width << "\n";                       \
62     cout << "  prec:  " << got.precision() << "\n";                     \
63     cout << "  flags: " << hex << (unsigned long) got.flags() << "\n";  \
64   } while (0)
65
66 #define ABORT() \
67   do {          \
68     DUMP ();    \
69     abort ();   \
70   } while (0)
71
72 void
73 check_mpz (void)
74 {
75   static const struct {
76     const char     *z;
77     const char     *want;
78     ios::fmtflags  flags;
79     int            width;
80     int            precision;
81     char           fill;
82
83   } data[] = {
84
85     { "0", "0", ios::dec },
86
87     { "0", "0", ios::oct },
88     { "0", "0", ios::oct | ios::showbase },
89
90     { "0", "0", ios::hex },
91     { "0", "0x0", ios::hex | ios::showbase },
92     { "0", "0X0", ios::hex | ios::showbase | ios::uppercase },
93
94     { "1", "****1", ios::dec, 5, 0, '*' },
95
96     { "-1", "   -1",  ios::dec | ios::right,    5 },
97     { "-1", "-   1",  ios::dec | ios::internal, 5 },
98     { "-1", "-1   ",  ios::dec | ios::left,     5 },
99
100     { "1", "   0x1", ios::hex | ios::showbase | ios::right,    6 },
101     { "1", "0x   1", ios::hex | ios::showbase | ios::internal, 6 },
102     { "1", "0x1   ", ios::hex | ios::showbase | ios::left,     6 },
103
104     { "1", "   +0x1", ios::hex | ios::showbase | ios::showpos | ios::right,
105       7 },
106     { "1", "+0x   1", ios::hex | ios::showbase | ios::showpos | ios::internal,
107       7 },
108     { "1", "+0x1   ", ios::hex | ios::showbase | ios::showpos | ios::left,
109       7 },
110
111     {  "123",    "7b", ios::hex },
112     {  "123",    "7B", ios::hex | ios::uppercase },
113     {  "123",  "0x7b", ios::hex | ios::showbase },
114     {  "123",  "0X7B", ios::hex | ios::showbase | ios::uppercase },
115     { "-123", "-0x7b", ios::hex | ios::showbase },
116     { "-123", "-0X7B", ios::hex | ios::showbase | ios::uppercase },
117
118     {  "123",   "173", ios::oct },
119     {  "123",   "173", ios::oct | ios::uppercase },
120     {  "123",  "0173", ios::oct | ios::showbase },
121     {  "123",  "0173", ios::oct | ios::showbase | ios::uppercase },
122     { "-123", "-0173", ios::oct | ios::showbase },
123     { "-123", "-0173", ios::oct | ios::showbase | ios::uppercase },
124
125   };
126
127   size_t  i;
128   mpz_t   z;
129
130   mpz_init (z);
131
132   for (i = 0; i < numberof (data); i++)
133     {
134       mpz_set_str_or_abort (z, data[i].z, 0);
135
136       if (option_check_standard
137           && mpz_fits_slong_p (z)
138
139           // no negatives or showpos in hex or oct
140           && (((data[i].flags & ios::basefield) == ios::hex
141                || (data[i].flags & ios::basefield) == ios::oct)
142               ? (mpz_sgn (z) >= 0
143                  && ! (data[i].flags & ios::showpos))
144               : 1)
145           )
146         {
147           ostringstream  got;
148           long  n = mpz_get_si (z);
149           CALL (got << n);
150           if (got.str().compare (data[i].want) != 0)
151             {
152               cout << "check_mpz data[" << i
153                    << "] doesn't match standard ostream output\n";
154               cout << "  z:     " << data[i].z << "\n";
155               cout << "  n:     " << n << "\n";
156               DUMP ();
157             }
158         }
159
160       {
161         ostringstream  got;
162         CALL (got << z);
163         if (got.str().compare (data[i].want) != 0)
164           {
165             cout << "mpz operator<< wrong, data[" << i << "]\n";
166             cout << "  z:     " << data[i].z << "\n";
167             ABORT ();
168           }
169       }
170     }
171
172   mpz_clear (z);
173 }
174
175 void
176 check_mpq (void)
177 {
178   static const struct {
179     const char     *q;
180     const char     *want;
181     ios::fmtflags  flags;
182     int            width;
183     int            precision;
184     char           fill;
185
186   } data[] = {
187
188     { "0", "0", ios::dec },
189     { "0", "0", ios::hex },
190     { "0", "0x0", ios::hex | ios::showbase },
191     { "0", "0X0", ios::hex | ios::showbase | ios::uppercase },
192
193     { "5/8", "5/8", ios::dec },
194     { "5/8", "0X5/0X8", ios::hex | ios::showbase | ios::uppercase },
195
196     // zero denominator with showbase
197     { "0/0",   "       0/0", ios::oct | ios::showbase, 10 },
198     { "0/0",   "       0/0", ios::dec | ios::showbase, 10 },
199     { "0/0",   "   0x0/0x0", ios::hex | ios::showbase, 10 },
200     { "123/0", "    0173/0", ios::oct | ios::showbase, 10 },
201     { "123/0", "     123/0", ios::dec | ios::showbase, 10 },
202     { "123/0", "  0x7b/0x0", ios::hex | ios::showbase, 10 },
203     { "123/0", "  0X7B/0X0", ios::hex | ios::showbase | ios::uppercase, 10 },
204     { "0/123", "    0/0173", ios::oct | ios::showbase, 10 },
205     { "0/123", "     0/123", ios::dec | ios::showbase, 10 },
206     { "0/123", "  0x0/0x7b", ios::hex | ios::showbase, 10 },
207     { "0/123", "  0X0/0X7B", ios::hex | ios::showbase | ios::uppercase, 10 },
208   };
209
210   size_t  i;
211   mpq_t   q;
212
213   mpq_init (q);
214
215 #define mpq_integer_p(q)  (mpz_cmp_ui (mpq_denref(q), 1L) == 0)
216
217   for (i = 0; i < numberof (data); i++)
218     {
219       mpq_set_str_or_abort (q, data[i].q, 0);
220       MPZ_CHECK_FORMAT (mpq_numref (q));
221       MPZ_CHECK_FORMAT (mpq_denref (q));
222
223       if (option_check_standard
224           && mpz_fits_slong_p (mpq_numref(q))
225           && mpq_integer_p (q))
226         {
227           ostringstream  got;
228           long  n = mpz_get_si (mpq_numref(q));
229           CALL (got << n);
230           if (got.str().compare (data[i].want) != 0)
231             {
232               cout << "check_mpq data[" << i
233                    << "] doesn't match standard ostream output\n";
234               cout << "  q:     " << data[i].q << "\n";
235               cout << "  n:     " << n << "\n";
236               DUMP ();
237             }
238         }
239
240       {
241         ostringstream  got;
242         CALL (got << q);
243         if (got.str().compare (data[i].want) != 0)
244           {
245             cout << "mpq operator<< wrong, data[" << i << "]\n";
246             cout << "  q:     " << data[i].q << "\n";
247             ABORT ();
248           }
249       }
250     }
251
252   mpq_clear (q);
253 }
254
255
256 void
257 check_mpf (void)
258 {
259   static const struct {
260     const char     *f;
261     const char     *want;
262     ios::fmtflags  flags;
263     int            width;
264     int            precision;
265     char           fill;
266
267   } data[] = {
268
269     { "0", "0",            ios::dec },
270     { "0", "+0",           ios::dec | ios::showpos },
271     { "0", "0.00000",      ios::dec | ios::showpoint },
272     { "0", "0",            ios::dec | ios::fixed },
273     { "0", "0.",           ios::dec | ios::fixed | ios::showpoint },
274     { "0", "0.000000e+00", ios::dec | ios::scientific },
275     { "0", "0.000000e+00", ios::dec | ios::scientific | ios::showpoint },
276
277     { "0", "0",          ios::dec, 0, 4 },
278     { "0", "0.000",      ios::dec | ios::showpoint, 0, 4 },
279     { "0", "0.0000",     ios::dec | ios::fixed, 0, 4 },
280     { "0", "0.0000",     ios::dec | ios::fixed | ios::showpoint, 0, 4 },
281     { "0", "0.0000e+00", ios::dec | ios::scientific, 0, 4 },
282     { "0", "0.0000e+00", ios::dec | ios::scientific | ios::showpoint, 0, 4 },
283
284     { "1", "1",       ios::dec },
285     { "1", "+1",      ios::dec | ios::showpos },
286     { "1", "1.00000", ios::dec | ios::showpoint },
287     { "1", "1",       ios::dec | ios::fixed },
288     { "1", "1.",      ios::dec | ios::fixed | ios::showpoint },
289     { "1", "1.000000e+00",   ios::dec | ios::scientific },
290     { "1", "1.000000e+00",  ios::dec | ios::scientific | ios::showpoint },
291
292     { "1", "1",          ios::dec,                   0, 4 },
293     { "1", "1.000",      ios::dec | ios::showpoint,  0, 4 },
294     { "1", "1.0000",     ios::dec | ios::fixed,      0, 4 },
295     { "1", "1.0000",     ios::dec | ios::fixed | ios::showpoint, 0, 4 },
296     { "1", "1.0000e+00", ios::dec | ios::scientific, 0, 4 },
297     { "1", "1.0000e+00", ios::dec | ios::scientific | ios::showpoint, 0, 4 },
298
299     { "-1", "-1",        ios::dec | ios::showpos },
300
301     { "-1", "  -1",      ios::dec, 4 },
302     { "-1", "-  1",      ios::dec | ios::internal, 4 },
303     { "-1", "-1  ",      ios::dec | ios::left, 4 },
304
305     { "-1", "  -0x1",    ios::hex | ios::showbase, 6 },
306     { "-1", "-0x  1",    ios::hex | ios::showbase | ios::internal, 6 },
307     { "-1", "-0x1  ",    ios::hex | ios::showbase | ios::left, 6 },
308
309     {    "1", "*********1", ios::dec, 10, 4, '*' },
310     { "1234", "******1234", ios::dec, 10, 4, '*' },
311     { "1234", "*****1234.", ios::dec | ios::showpoint, 10, 4, '*' },
312
313     { "12345", "1.23e+04", ios::dec, 0, 3 },
314
315     { "12345", "12345.", ios::dec | ios::fixed | ios::showpoint },
316
317     { "1.9999999",    "2",     ios::dec, 0, 1 },
318     { "1.0009999999", "1.001", ios::dec, 0, 4 },
319     { "1.0001",       "1",     ios::dec, 0, 4 },
320     { "1.0004",       "1",     ios::dec, 0, 4 },
321     { "1.000555",     "1.001", ios::dec, 0, 4 },
322
323     { "1.0002",       "1.000", ios::dec | ios::fixed, 0, 3 },
324     { "1.0008",       "1.001", ios::dec | ios::fixed, 0, 3 },
325
326     { "0", "0", ios::hex },
327     { "0", "0x0", ios::hex | ios::showbase },
328     { "0", "0X0", ios::hex | ios::showbase | ios::uppercase },
329     { "123",   "7b", ios::hex },
330     { "123", "0x7b", ios::hex | ios::showbase },
331     { "123", "0X7B", ios::hex | ios::showbase | ios::uppercase },
332
333     { "0", "0.000@+00", ios::hex | ios::scientific, 0, 3 },
334     { "256", "1.000@+02", ios::hex | ios::scientific, 0, 3 },
335
336     { "123",   "7.b@+01", ios::hex | ios::scientific, 0, 1 },
337     { "123",   "7.B@+01", ios::hex | ios::scientific | ios::uppercase, 0, 1 },
338     { "123", "0x7.b@+01", ios::hex | ios::scientific | ios::showbase, 0, 1 },
339     { "123", "0X7.B@+01",
340       ios::hex | ios::scientific | ios::showbase | ios::uppercase, 0, 1 },
341
342     { "1099511627776", "1.0@+10", ios::hex | ios::scientific, 0, 1 },
343     { "1099511627776", "1.0@+10",
344       ios::hex | ios::scientific | ios::uppercase, 0, 1 },
345
346     { "0.0625", "1.00@-01", ios::hex | ios::scientific, 0, 2 },
347
348     { "0", "0", ios::oct },
349     { "123",  "173", ios::oct },
350     { "123", "0173", ios::oct | ios::showbase },
351
352     // octal showbase suppressed for 0
353     { "0", "0", ios::oct | ios::showbase },
354     { ".125",    "00.1",  ios::oct | ios::showbase, 0, 1 },
355     { ".015625", "00.01", ios::oct | ios::showbase, 0, 2 },
356     { ".125",    "00.1",  ios::fixed | ios::oct | ios::showbase, 0, 1 },
357     { ".015625", "0.0",   ios::fixed | ios::oct | ios::showbase, 0, 1 },
358     { ".015625", "00.01", ios::fixed | ios::oct | ios::showbase, 0, 2 },
359
360     {  "0.125",  "1.000000e-01", ios::oct | ios::scientific },
361     {  "0.125", "+1.000000e-01", ios::oct | ios::scientific | ios::showpos },
362     { "-0.125", "-1.000000e-01", ios::oct | ios::scientific },
363     { "-0.125", "-1.000000e-01", ios::oct | ios::scientific | ios::showpos },
364
365     { "0", "0.000e+00", ios::oct | ios::scientific, 0, 3 },
366     { "256",  "4.000e+02", ios::oct | ios::scientific, 0, 3 },
367     { "256", "04.000e+02", ios::oct | ios::scientific | ios::showbase, 0, 3 },
368     { "256",  "4.000E+02", ios::oct | ios::scientific | ios::uppercase, 0, 3 },
369     { "256", "04.000E+02",
370       ios::oct | ios::scientific | ios::showbase | ios::uppercase, 0, 3 },
371
372     { "16777216",    "1.000000e+08", ios::oct | ios::scientific },
373     { "16777216",    "1.000000E+08",
374       ios::oct | ios::scientific | ios::uppercase },
375     { "16777216",   "01.000000e+08",
376       ios::oct | ios::scientific | ios::showbase },
377     { "16777216",   "01.000000E+08",
378       ios::oct | ios::scientific | ios::showbase | ios::uppercase },
379     { "16777216",  "+01.000000e+08",
380       ios::oct | ios::scientific | ios::showbase | ios::showpos },
381     { "16777216",  "+01.000000E+08", ios::oct | ios::scientific
382       | ios::showbase | ios::showpos | ios::uppercase },
383     { "-16777216", "-01.000000e+08",
384       ios::oct | ios::scientific | ios::showbase | ios::showpos },
385     { "-16777216", "-01.000000E+08", ios::oct | ios::scientific
386       | ios::showbase | ios::showpos | ios::uppercase },
387
388   };
389
390   size_t  i;
391   mpf_t   f, f2;
392   double  d;
393
394   mpf_init (f);
395   mpf_init (f2);
396
397   for (i = 0; i < numberof (data); i++)
398     {
399       mpf_set_str_or_abort (f, data[i].f, 0);
400
401       d = mpf_get_d (f);
402       mpf_set_d (f2, d);
403       if (option_check_standard && mpf_cmp (f, f2) == 0
404           && ! (data[i].flags & (ios::hex | ios::oct | ios::showbase)))
405         {
406           ostringstream  got;
407           CALL (got << d);
408           if (got.str().compare (data[i].want) != 0)
409             {
410               cout << "check_mpf data[" << i
411                    << "] doesn't match standard ostream output\n";
412               cout << "  f:     " << data[i].f << "\n";
413               cout << "  d:     " << d << "\n";
414               DUMP ();
415             }
416         }
417
418       {
419         ostringstream  got;
420         CALL (got << f);
421         if (got.str().compare (data[i].want) != 0)
422           {
423             cout << "mpf operator<< wrong, data[" << i << "]\n";
424             cout << "  f:     " << data[i].f << "\n";
425             ABORT ();
426           }
427       }
428     }
429
430   mpf_clear (f);
431   mpf_clear (f2);
432 }
433
434
435
436 int
437 main (int argc, char *argv[])
438 {
439   if (argc > 1 && strcmp (argv[1], "-s") == 0)
440     option_check_standard = 1;
441
442   tests_start ();
443
444   check_mpz ();
445   check_mpq ();
446   check_mpf ();
447
448   tests_end ();
449   return 0;
450 }