github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/mini-gmp/tests/t-signed.c (about) 1 /* Exercise some mpz_..._si functions. 2 3 Copyright 2013, 2016 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 <limits.h> 21 #include <stdio.h> 22 #include <stdlib.h> 23 24 #include "testutils.h" 25 26 /* Always called with sz fitting in a signed long, and si is the 27 corresponding value. */ 28 int 29 check_si (const mpz_t sz, long si) 30 { 31 mpz_t t; 32 33 /* Checks on sz/si */ 34 if ((mpz_cmp_si (sz, si)) != 0) 35 { 36 printf ("mpz_cmp_si (sz, %ld) != 0.\n", si); 37 return 0; 38 } 39 if (mpz_get_si (sz) != si) 40 { 41 printf ("mpz_get_si (sz) != %ld.\n", si); 42 return 0; 43 } 44 45 mpz_init_set_si (t, si); 46 47 if (mpz_cmp (t, sz) != 0) 48 { 49 printf ("mpz_init_set_si (%ld) failed.\n", si); 50 printf (" got="); mpz_out_str (stdout, 10, t); printf ("\n"); 51 return 0; 52 } 53 54 mpz_clear (t); 55 return 1; 56 } 57 58 /* Called with mpz_cmp (sz, oz) == c. If sz fits in a signed long, 59 si is the coresponding value, and similarly for oz and oi. */ 60 void 61 check_si_cmp (const mpz_t sz, const mpz_t oz, long si, long oi, int c) 62 { 63 if (mpz_cmp (sz, oz) != c) 64 { 65 printf ("mpz_cmp (sz, oz) != %i.\n", c); 66 goto fail; 67 } 68 69 if (mpz_fits_slong_p (sz)) 70 { 71 if (!check_si (sz, si)) 72 goto fail; 73 if (mpz_cmp_si (oz, si) != -c) 74 { 75 printf ("mpz_cmp_si (oz, %ld) != %i.\n", si, -c); 76 goto fail; 77 } 78 } 79 else 80 { 81 if (mpz_cmp_si (sz, si) != c) 82 { 83 printf ("mpz_cmp_si (sz, %ld) != %i.\n", si, c); 84 goto fail; 85 } 86 if (mpz_cmp_si (sz, -c) != c) 87 { 88 printf ("mpz_cmp_si (sz, %i) != %i.\n", -c, c); 89 goto fail; 90 } 91 } 92 if (mpz_fits_slong_p (oz)) 93 { 94 if (!check_si (oz, oi)) 95 goto fail; 96 if (mpz_cmp_si (sz, oi) != c) 97 { 98 printf ("mpz_cmp_si (sz, %ld) != %i.\n", oi, c); 99 goto fail; 100 } 101 } 102 return; 103 104 fail: 105 printf (" sz="); mpz_out_str (stdout, 10, sz); printf ("\n"); 106 printf (" si=%ld\n", si); 107 printf (" oz="); mpz_out_str (stdout, 10, oz); printf ("\n"); 108 printf (" oi=%ld\n", si); 109 abort (); 110 } 111 112 void 113 try_op_si (int c) 114 { 115 long si, oi; 116 mpz_t sz, oz; 117 unsigned overflow_count; 118 119 si = c; 120 mpz_init_set_si (sz, si); 121 122 oi = si; 123 mpz_init_set (oz, sz); 124 125 /* To get a few tests with operands straddling the border, don't 126 stop at the very first operand exceeding a signed long. */ 127 for (overflow_count = 0; overflow_count < 10; ) 128 { 129 /* c * 2^k */ 130 mpz_mul_2exp (sz, sz, 1); 131 if (mpz_fits_slong_p (sz)) 132 si *= 2; 133 else 134 overflow_count++; 135 136 check_si_cmp (sz, oz, si, oi, c); 137 138 /* c * (2^k + 1) */ 139 if (c == -1) 140 mpz_sub_ui (oz, sz, 1); 141 else 142 mpz_add_ui (oz, sz, 1); 143 if (mpz_fits_slong_p (oz)) 144 oi = si + c; 145 else 146 overflow_count++; 147 check_si_cmp (oz, sz, oi, si, c); 148 149 /* c * (2^K - 1) */ 150 mpz_mul_si (oz, sz, 2*c); 151 if (c == -1) 152 mpz_ui_sub (oz, 1, oz); /* oz = sz * 2 + 1 */ 153 else 154 mpz_sub_ui (oz, oz, 1); /* oz = sz * 2 - 1 */ 155 if (mpz_fits_slong_p (oz)) 156 oi = (si - c) * 2 + c; 157 else 158 overflow_count++; 159 160 check_si_cmp (oz, sz, oi, si, c); 161 }; 162 163 mpz_clear (sz); 164 mpz_clear (oz); 165 } 166 167 void 168 try_fits_slong_p (void) 169 { 170 mpz_t x; 171 mpz_init_set_si (x, LONG_MAX); 172 if (!mpz_fits_slong_p (x)) 173 { 174 printf ("mpz_fits_slong_p (LONG_MAX) false!\n"); 175 abort (); 176 } 177 mpz_add_ui (x, x, 1); 178 if (mpz_fits_slong_p (x)) 179 { 180 printf ("mpz_fits_slong_p (LONG_MAX + 1) true!\n"); 181 abort (); 182 } 183 mpz_set_si (x, LONG_MIN); 184 if (!mpz_fits_slong_p (x)) 185 { 186 printf ("mpz_fits_slong_p (LONG_MIN) false!\n"); 187 abort (); 188 } 189 mpz_sub_ui (x, x, 1); 190 if (mpz_fits_slong_p (x)) 191 { 192 printf ("mpz_fits_slong_p (LONG_MIN - 1) true!\n"); 193 abort (); 194 } 195 196 mpz_clear (x); 197 } 198 199 void 200 testmain (int argc, char *argv[]) 201 { 202 try_fits_slong_p (); 203 try_op_si (-1); 204 try_op_si (1); 205 }