source: trunk/third/gmp/tests/cxx/t-ostream.cc @ 18191

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