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