github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/mpz/t-limbs.c (about) 1 /* Test mpz_limbs_* functions 2 3 Copyright 2013 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 <stdlib.h> 21 #include <stdio.h> 22 23 #include "gmp.h" 24 #include "gmp-impl.h" 25 #include "tests.h" 26 27 #define COUNT 100 28 #define BITSIZE 500 29 30 /* Like mpz_add. For simplicity, support positive inputs only. */ 31 static void 32 alt_add (mpz_ptr r, mpz_srcptr a, mpz_srcptr b) 33 { 34 mp_size_t an = mpz_size (a); 35 mp_size_t bn = mpz_size (b); 36 mp_ptr rp; 37 38 ASSERT (an > 0); 39 ASSERT (bn > 0); 40 if (an < bn) 41 { 42 MP_SIZE_T_SWAP (an, bn); 43 MPZ_SRCPTR_SWAP (a, b); 44 } 45 rp = mpz_limbs_modify (r, an + 1); 46 rp[an] = mpn_add (rp, mpz_limbs_read (a), an, mpz_limbs_read (b), bn); 47 mpz_limbs_finish (r, an + 1); 48 } 49 50 static void 51 check_funcs (const char *name, 52 void (*f)(mpz_ptr, mpz_srcptr, mpz_srcptr), 53 void (*ref_f)(mpz_ptr, mpz_srcptr, mpz_srcptr), 54 mpz_srcptr a, mpz_srcptr b) 55 { 56 mpz_t r, ref; 57 mpz_inits (r, ref, NULL); 58 59 ref_f (ref, a, b); 60 MPZ_CHECK_FORMAT (ref); 61 f (r, a, b); 62 MPZ_CHECK_FORMAT (r); 63 64 if (mpz_cmp (r, ref) != 0) 65 { 66 printf ("%s failed, abits %u, bbits %u\n", 67 name, 68 (unsigned) mpz_sizeinbase (a, 2), 69 (unsigned) mpz_sizeinbase (b, 2)); 70 gmp_printf ("a = %Zx\n", a); 71 gmp_printf ("b = %Zx\n", b); 72 gmp_printf ("r = %Zx (bad)\n", r); 73 gmp_printf ("ref = %Zx\n", ref); 74 abort (); 75 } 76 mpz_clears (r, ref, NULL); 77 } 78 79 static void 80 check_add (void) 81 { 82 gmp_randstate_ptr rands = RANDS; 83 mpz_t bs, a, b; 84 unsigned i; 85 mpz_inits (bs, a, b, NULL); 86 for (i = 0; i < COUNT; i++) 87 { 88 mpz_urandomb (bs, rands, 32); 89 mpz_rrandomb (a, rands, 1 + mpz_get_ui (bs) % BITSIZE); 90 mpz_urandomb (bs, rands, 32); 91 mpz_rrandomb (b, rands, 1 + mpz_get_ui (bs) % BITSIZE); 92 93 check_funcs ("add", alt_add, mpz_add, a, b); 94 } 95 mpz_clears (bs, a, b, NULL); 96 } 97 98 static void 99 alt_mul (mpz_ptr r, mpz_srcptr a, mpz_srcptr b) 100 { 101 mp_size_t an = mpz_size (a); 102 mp_size_t bn = mpz_size (b); 103 mp_srcptr ap, bp; 104 TMP_DECL; 105 106 TMP_MARK; 107 108 ASSERT (an > 0); 109 ASSERT (bn > 0); 110 if (an < bn) 111 { 112 MP_SIZE_T_SWAP (an, bn); 113 MPZ_SRCPTR_SWAP (a, b); 114 } 115 /* NOTE: This copying seems unnecessary; better to allocate new 116 result area, and free the old area when done. */ 117 if (r == a) 118 { 119 mp_ptr tp = TMP_ALLOC_LIMBS (an); 120 MPN_COPY (tp, mpz_limbs_read (a), an); 121 ap = tp; 122 bp = (a == b) ? ap : mpz_limbs_read (b); 123 } 124 else if (r == b) 125 { 126 mp_ptr tp = TMP_ALLOC_LIMBS (bn); 127 MPN_COPY (tp, mpz_limbs_read (b), bn); 128 bp = tp; 129 ap = mpz_limbs_read (a); 130 } 131 else 132 { 133 ap = mpz_limbs_read (a); 134 bp = mpz_limbs_read (b); 135 } 136 mpn_mul (mpz_limbs_write (r, an + bn), 137 ap, an, bp, bn); 138 139 mpz_limbs_finish (r, an + bn); 140 } 141 142 void 143 check_mul (void) 144 { 145 gmp_randstate_ptr rands = RANDS; 146 mpz_t bs, a, b; 147 unsigned i; 148 mpz_inits (bs, a, b, NULL); 149 for (i = 0; i < COUNT; i++) 150 { 151 mpz_urandomb (bs, rands, 32); 152 mpz_rrandomb (a, rands, 1 + mpz_get_ui (bs) % BITSIZE); 153 mpz_urandomb (bs, rands, 32); 154 mpz_rrandomb (b, rands, 1 + mpz_get_ui (bs) % BITSIZE); 155 156 check_funcs ("mul", alt_mul, mpz_mul, a, b); 157 } 158 mpz_clears (bs, a, b, NULL); 159 } 160 161 #define MAX_SIZE 100 162 163 static void 164 check_roinit (void) 165 { 166 gmp_randstate_ptr rands = RANDS; 167 mpz_t bs, a, b, r, ref; 168 unsigned i; 169 170 mpz_inits (bs, a, b, r, ref, NULL); 171 172 for (i = 0; i < COUNT; i++) 173 { 174 mp_srcptr ap, bp; 175 mp_size_t an, bn; 176 mpz_urandomb (bs, rands, 32); 177 mpz_rrandomb (a, rands, 1 + mpz_get_ui (bs) % BITSIZE); 178 mpz_urandomb (bs, rands, 32); 179 mpz_rrandomb (b, rands, 1 + mpz_get_ui (bs) % BITSIZE); 180 181 an = mpz_size (a); 182 ap = mpz_limbs_read (a); 183 bn = mpz_size (b); 184 bp = mpz_limbs_read (b); 185 186 mpz_add (ref, a, b); 187 { 188 mpz_t a1, b1; 189 #if __STDC_VERSION__ >= 199901 190 const mpz_t a2 = MPZ_ROINIT_N ( (mp_ptr) ap, an); 191 const mpz_t b2 = MPZ_ROINIT_N ( (mp_ptr) bp, bn); 192 193 mpz_set_ui (r, 0); 194 mpz_add (r, a2, b2); 195 if (mpz_cmp (r, ref) != 0) 196 { 197 printf ("MPZ_ROINIT_N failed\n"); 198 gmp_printf ("a = %Zx\n", a); 199 gmp_printf ("b = %Zx\n", b); 200 gmp_printf ("r = %Zx (bad)\n", r); 201 gmp_printf ("ref = %Zx\n", ref); 202 abort (); 203 } 204 #endif 205 mpz_set_ui (r, 0); 206 mpz_add (r, mpz_roinit_n (a1, ap, an), mpz_roinit_n (b1, bp, bn)); 207 if (mpz_cmp (r, ref) != 0) 208 { 209 printf ("mpz_roinit_n failed\n"); 210 gmp_printf ("a = %Zx\n", a); 211 gmp_printf ("b = %Zx\n", b); 212 gmp_printf ("r = %Zx (bad)\n", r); 213 gmp_printf ("ref = %Zx\n", ref); 214 abort (); 215 } 216 } 217 } 218 mpz_clears (bs, a, b, r, ref, NULL); 219 } 220 221 int 222 main (int argc, char *argv[]) 223 { 224 tests_start (); 225 tests_end (); 226 227 check_add (); 228 check_mul (); 229 check_roinit (); 230 231 return 0; 232 233 }