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 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 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 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 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