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