Tizen 2.1 base
[external/gmp.git] / tests / mpf / t-get_si.c
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 }