xref: /netbsd-src/external/lgpl3/gmp/dist/tests/mpf/t-get_si.c (revision 413d532bcc3f62d122e56d92e13ac64825a40baf)
1 /* Exercise mpz_get_si.
2 
3 Copyright 2000, 2001 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 http://www.gnu.org/licenses/.  */
19 
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include "gmp.h"
23 #include "gmp-impl.h"
24 #include "tests.h"
25 
26 
27 void
28 check_data (void)
29 {
30   static const struct {
31     int         base;
32     const char  *f;
33     long        want;
34   } data[] = {
35     { 10, "0",      0L },
36     { 10, "1",      1L },
37     { 10, "-1",     -1L },
38     { 10, "2",      2L },
39     { 10, "-2",     -2L },
40     { 10, "12345",  12345L },
41     { 10, "-12345", -12345L },
42 
43     /* fraction bits ignored */
44     { 10, "0.5",    0L },
45     { 10, "-0.5",   0L },
46     { 10, "1.1",    1L },
47     { 10, "-1.1",   -1L },
48     { 10, "1.9",    1L },
49     { 10, "-1.9",   -1L },
50     { 16, "1.000000000000000000000000000000000000000000000000001", 1L },
51     { 16, "-1.000000000000000000000000000000000000000000000000001", -1L },
52 
53     /* low bits extracted (this is undocumented) */
54     { 16, "1000000000000000000000000000000000000000000000000001", 1L },
55     { 16, "-1000000000000000000000000000000000000000000000000001", -1L },
56   };
57 
58   int    i;
59   mpf_t  f;
60   long   got;
61 
62   mpf_init2 (f, 2000L);
63   for (i = 0; i < numberof (data); i++)
64     {
65       mpf_set_str_or_abort (f, data[i].f, data[i].base);
66 
67       got = mpf_get_si (f);
68       if (got != data[i].want)
69 	{
70 	  printf ("mpf_get_si wrong at data[%d]\n", i);
71 	  printf ("   f     \"%s\"\n", data[i].f);
72 	  printf ("     dec "); mpf_out_str (stdout, 10, 0, f); printf ("\n");
73 	  printf ("     hex "); mpf_out_str (stdout, 16, 0, f); printf ("\n");
74 	  printf ("     size %ld\n", (long) SIZ(f));
75 	  printf ("     exp  %ld\n", (long) EXP(f));
76 	  printf ("   got   %ld (0x%lX)\n", got, got);
77 	  printf ("   want  %ld (0x%lX)\n", data[i].want, data[i].want);
78 	  abort();
79 	}
80     }
81   mpf_clear (f);
82 }
83 
84 
85 void
86 check_max (void)
87 {
88   mpf_t  f;
89   long   want;
90   long   got;
91 
92   mpf_init2 (f, 200L);
93 
94 #define CHECK_MAX(name)                                         \
95   if (got != want)                                              \
96     {                                                           \
97       printf ("mpf_get_si wrong on %s\n", name);                \
98       printf ("   f    ");                                      \
99       mpf_out_str (stdout, 10, 0, f); printf (", hex ");        \
100       mpf_out_str (stdout, 16, 0, f); printf ("\n");            \
101       printf ("   got  %ld, hex %lX\n", got, got);              \
102       printf ("   want %ld, hex %lX\n", want, want);            \
103       abort();                                                  \
104     }
105 
106   want = LONG_MAX;
107   mpf_set_si (f, want);
108   got = mpf_get_si (f);
109   CHECK_MAX ("LONG_MAX");
110 
111   want = LONG_MIN;
112   mpf_set_si (f, want);
113   got = mpf_get_si (f);
114   CHECK_MAX ("LONG_MIN");
115 
116   mpf_clear (f);
117 }
118 
119 
120 void
121 check_limbdata (void)
122 {
123 #define M  GMP_NUMB_MAX
124 
125   static const struct {
126     mp_exp_t       exp;
127     mp_size_t      size;
128     mp_limb_t      d[10];
129     unsigned long  want;
130 
131   } data[] = {
132 
133     /* in the comments here, a "_" indicates a digit (ie. limb) position not
134        included in the d data, and therefore zero */
135 
136     { 0, 0, { 0 }, 0L },    /* 0 */
137 
138     { 1,  1, { 1 }, 1L },   /* 1 */
139     { 1, -1, { 1 }, -1L },  /* -1 */
140 
141     { 0,  1, { 1 }, 0L },   /* .1 */
142     { 0, -1, { 1 }, 0L },   /* -.1 */
143 
144     { -1,  1, { 1 }, 0L },  /* ._1 */
145     { -1, -1, { 1 }, 0L },  /* -._1 */
146 
147     { -999,          1, { 1 }, 0L },   /* .___1 small */
148     { MP_EXP_T_MIN,  1, { 1 }, 0L },   /* .____1 very small */
149 
150     { 999,          1, { 1 }, 0L },    /* 1____. big */
151     { MP_EXP_T_MAX, 1, { 1 }, 0L },    /* 1_____. very big */
152 
153     { 1, 2, { 999, 2 }, 2L },                  /* 2.9 */
154     { 5, 8, { 7, 8, 9, 3, 0, 0, 0, 1 }, 3L },  /* 10003.987 */
155 
156     { 2, 2, { M, M },    LONG_MAX }, /* FF. */
157     { 2, 2, { M, M, M }, LONG_MAX }, /* FF.F */
158     { 3, 3, { M, M, M }, LONG_MAX }, /* FFF. */
159 
160 #if GMP_NUMB_BITS >= BITS_PER_ULONG
161     /* normal case, numb bigger than long */
162     { 2,  1, { 1 },    0L },      /* 1_. */
163     { 2,  2, { 0, 1 }, 0L },      /* 10. */
164     { 2,  2, { 999, 1 }, 999L },  /* 19. */
165     { 3,  2, { 999, 1 }, 0L },    /* 19_. */
166 
167 #else
168     /* nails case, numb smaller than long */
169     { 2,  1, { 1 }, 1L << GMP_NUMB_BITS },  /* 1_. */
170     { 3,  1, { 1 }, 0L },                   /* 1__. */
171 
172     { 2,  2, { 99, 1 },    99L + (1L << GMP_NUMB_BITS) },  /* 19. */
173     { 3,  2, { 1, 99 },    1L << GMP_NUMB_BITS },          /* 91_. */
174     { 3,  3, { 0, 1, 99 }, 1L << GMP_NUMB_BITS },          /* 910. */
175 
176 #endif
177   };
178 
179   mpf_t          f;
180   unsigned long  got;
181   int            i;
182   mp_limb_t      buf[20 + numberof(data[i].d)];
183 
184   for (i = 0; i < numberof (data); i++)
185     {
186       refmpn_fill (buf, 10, CNST_LIMB(0xDEADBEEF));
187       refmpn_copy (buf+10, data[i].d, ABS(data[i].size));
188       refmpn_fill (buf+10+ABS(data[i].size), 10, CNST_LIMB(0xDEADBEEF));
189 
190       PTR(f) = buf+10;
191       EXP(f) = data[i].exp;
192       SIZ(f) = data[i].size;
193       PREC(f) = numberof (data[i].d);
194       MPF_CHECK_FORMAT (f);
195 
196       got = mpf_get_si (f);
197       if (got != data[i].want)
198 	{
199 	  printf    ("mpf_get_si wrong at limb data[%d]\n", i);
200 	  mpf_trace ("  f", f);
201 	  mpn_trace ("  d", data[i].d, data[i].size);
202 	  printf    ("  size %ld\n", (long) data[i].size);
203 	  printf    ("  exp %ld\n", (long) data[i].exp);
204 	  printf    ("  got   %lu (0x%lX)\n", got, got);
205 	  printf    ("  want  %lu (0x%lX)\n", data[i].want, data[i].want);
206 	  abort();
207 	}
208     }
209 }
210 
211 
212 int
213 main (void)
214 {
215   tests_start ();
216 
217   check_data ();
218   check_max ();
219   check_limbdata ();
220 
221   tests_end ();
222   exit (0);
223 }
224