xref: /netbsd-src/external/lgpl3/gmp/dist/tests/mpf/t-get_si.c (revision 7788a0781fe6ff2cce37368b4578a7ade0850cb1)
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.
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 <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