1 1.1 mrg /* Test mpz_limbs_* functions 2 1.1 mrg 3 1.1 mrg Copyright 2013 Free Software Foundation, Inc. 4 1.1 mrg 5 1.1 mrg This file is part of the GNU MP Library test suite. 6 1.1 mrg 7 1.1 mrg The GNU MP Library test suite is free software; you can redistribute it 8 1.1 mrg and/or modify it under the terms of the GNU General Public License as 9 1.1 mrg published by the Free Software Foundation; either version 3 of the License, 10 1.1 mrg or (at your option) any later version. 11 1.1 mrg 12 1.1 mrg The GNU MP Library test suite is distributed in the hope that it will be 13 1.1 mrg useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 15 1.1 mrg Public License for more details. 16 1.1 mrg 17 1.1 mrg You should have received a copy of the GNU General Public License along with 18 1.1 mrg the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ 19 1.1 mrg 20 1.1 mrg #include <stdlib.h> 21 1.1 mrg #include <stdio.h> 22 1.1 mrg 23 1.1 mrg #include "gmp-impl.h" 24 1.1 mrg #include "tests.h" 25 1.1 mrg 26 1.1 mrg #define COUNT 100 27 1.1 mrg #define BITSIZE 500 28 1.1 mrg 29 1.1 mrg /* Like mpz_add. For simplicity, support positive inputs only. */ 30 1.1 mrg static void 31 1.1 mrg alt_add (mpz_ptr r, mpz_srcptr a, mpz_srcptr b) 32 1.1 mrg { 33 1.1 mrg mp_size_t an = mpz_size (a); 34 1.1 mrg mp_size_t bn = mpz_size (b); 35 1.1 mrg mp_ptr rp; 36 1.1 mrg 37 1.1 mrg ASSERT (an > 0); 38 1.1 mrg ASSERT (bn > 0); 39 1.1 mrg if (an < bn) 40 1.1 mrg { 41 1.1 mrg MP_SIZE_T_SWAP (an, bn); 42 1.1 mrg MPZ_SRCPTR_SWAP (a, b); 43 1.1 mrg } 44 1.1 mrg rp = mpz_limbs_modify (r, an + 1); 45 1.1 mrg rp[an] = mpn_add (rp, mpz_limbs_read (a), an, mpz_limbs_read (b), bn); 46 1.1 mrg mpz_limbs_finish (r, an + 1); 47 1.1 mrg } 48 1.1 mrg 49 1.1 mrg static void 50 1.1 mrg check_funcs (const char *name, 51 1.1 mrg void (*f)(mpz_ptr, mpz_srcptr, mpz_srcptr), 52 1.1 mrg void (*ref_f)(mpz_ptr, mpz_srcptr, mpz_srcptr), 53 1.1 mrg mpz_srcptr a, mpz_srcptr b) 54 1.1 mrg { 55 1.1 mrg mpz_t r, ref; 56 1.1 mrg mpz_inits (r, ref, NULL); 57 1.1 mrg 58 1.1 mrg ref_f (ref, a, b); 59 1.1 mrg MPZ_CHECK_FORMAT (ref); 60 1.1 mrg f (r, a, b); 61 1.1 mrg MPZ_CHECK_FORMAT (r); 62 1.1 mrg 63 1.1 mrg if (mpz_cmp (r, ref) != 0) 64 1.1 mrg { 65 1.1 mrg printf ("%s failed, abits %u, bbits %u\n", 66 1.1 mrg name, 67 1.1 mrg (unsigned) mpz_sizeinbase (a, 2), 68 1.1 mrg (unsigned) mpz_sizeinbase (b, 2)); 69 1.1 mrg gmp_printf ("a = %Zx\n", a); 70 1.1 mrg gmp_printf ("b = %Zx\n", b); 71 1.1 mrg gmp_printf ("r = %Zx (bad)\n", r); 72 1.1 mrg gmp_printf ("ref = %Zx\n", ref); 73 1.1 mrg abort (); 74 1.1 mrg } 75 1.1 mrg mpz_clears (r, ref, NULL); 76 1.1 mrg } 77 1.1 mrg 78 1.1 mrg static void 79 1.1 mrg check_add (void) 80 1.1 mrg { 81 1.1 mrg gmp_randstate_ptr rands = RANDS; 82 1.1 mrg mpz_t bs, a, b; 83 1.1 mrg unsigned i; 84 1.1 mrg mpz_inits (bs, a, b, NULL); 85 1.1 mrg for (i = 0; i < COUNT; i++) 86 1.1 mrg { 87 1.1 mrg mpz_urandomb (bs, rands, 32); 88 1.1 mrg mpz_rrandomb (a, rands, 1 + mpz_get_ui (bs) % BITSIZE); 89 1.1 mrg mpz_urandomb (bs, rands, 32); 90 1.1 mrg mpz_rrandomb (b, rands, 1 + mpz_get_ui (bs) % BITSIZE); 91 1.1 mrg 92 1.1 mrg check_funcs ("add", alt_add, mpz_add, a, b); 93 1.1 mrg } 94 1.1 mrg mpz_clears (bs, a, b, NULL); 95 1.1 mrg } 96 1.1 mrg 97 1.1 mrg static void 98 1.1 mrg alt_mul (mpz_ptr r, mpz_srcptr a, mpz_srcptr b) 99 1.1 mrg { 100 1.1 mrg mp_size_t an = mpz_size (a); 101 1.1 mrg mp_size_t bn = mpz_size (b); 102 1.1 mrg mp_srcptr ap, bp; 103 1.1 mrg TMP_DECL; 104 1.1 mrg 105 1.1 mrg TMP_MARK; 106 1.1 mrg 107 1.1 mrg ASSERT (an > 0); 108 1.1 mrg ASSERT (bn > 0); 109 1.1 mrg if (an < bn) 110 1.1 mrg { 111 1.1 mrg MP_SIZE_T_SWAP (an, bn); 112 1.1 mrg MPZ_SRCPTR_SWAP (a, b); 113 1.1 mrg } 114 1.1 mrg /* NOTE: This copying seems unnecessary; better to allocate new 115 1.1 mrg result area, and free the old area when done. */ 116 1.1 mrg if (r == a) 117 1.1 mrg { 118 1.1 mrg mp_ptr tp = TMP_ALLOC_LIMBS (an); 119 1.1 mrg MPN_COPY (tp, mpz_limbs_read (a), an); 120 1.1 mrg ap = tp; 121 1.1 mrg bp = (a == b) ? ap : mpz_limbs_read (b); 122 1.1 mrg } 123 1.1 mrg else if (r == b) 124 1.1 mrg { 125 1.1 mrg mp_ptr tp = TMP_ALLOC_LIMBS (bn); 126 1.1 mrg MPN_COPY (tp, mpz_limbs_read (b), bn); 127 1.1 mrg bp = tp; 128 1.1 mrg ap = mpz_limbs_read (a); 129 1.1 mrg } 130 1.1 mrg else 131 1.1 mrg { 132 1.1 mrg ap = mpz_limbs_read (a); 133 1.1 mrg bp = mpz_limbs_read (b); 134 1.1 mrg } 135 1.1 mrg mpn_mul (mpz_limbs_write (r, an + bn), 136 1.1 mrg ap, an, bp, bn); 137 1.1 mrg 138 1.1 mrg mpz_limbs_finish (r, an + bn); 139 1.1 mrg } 140 1.1 mrg 141 1.1 mrg void 142 1.1 mrg check_mul (void) 143 1.1 mrg { 144 1.1 mrg gmp_randstate_ptr rands = RANDS; 145 1.1 mrg mpz_t bs, a, b; 146 1.1 mrg unsigned i; 147 1.1 mrg mpz_inits (bs, a, b, NULL); 148 1.1 mrg for (i = 0; i < COUNT; i++) 149 1.1 mrg { 150 1.1 mrg mpz_urandomb (bs, rands, 32); 151 1.1 mrg mpz_rrandomb (a, rands, 1 + mpz_get_ui (bs) % BITSIZE); 152 1.1 mrg mpz_urandomb (bs, rands, 32); 153 1.1 mrg mpz_rrandomb (b, rands, 1 + mpz_get_ui (bs) % BITSIZE); 154 1.1 mrg 155 1.1 mrg check_funcs ("mul", alt_mul, mpz_mul, a, b); 156 1.1 mrg } 157 1.1 mrg mpz_clears (bs, a, b, NULL); 158 1.1 mrg } 159 1.1 mrg 160 1.1 mrg #define MAX_SIZE 100 161 1.1 mrg 162 1.1 mrg static void 163 1.1 mrg check_roinit (void) 164 1.1 mrg { 165 1.1 mrg gmp_randstate_ptr rands = RANDS; 166 1.1 mrg mpz_t bs, a, b, r, ref; 167 1.1 mrg unsigned i; 168 1.1 mrg 169 1.1 mrg mpz_inits (bs, a, b, r, ref, NULL); 170 1.1 mrg 171 1.1 mrg for (i = 0; i < COUNT; i++) 172 1.1 mrg { 173 1.1 mrg mp_srcptr ap, bp; 174 1.1 mrg mp_size_t an, bn; 175 1.1 mrg mpz_urandomb (bs, rands, 32); 176 1.1 mrg mpz_rrandomb (a, rands, 1 + mpz_get_ui (bs) % BITSIZE); 177 1.1 mrg mpz_urandomb (bs, rands, 32); 178 1.1 mrg mpz_rrandomb (b, rands, 1 + mpz_get_ui (bs) % BITSIZE); 179 1.1 mrg 180 1.1 mrg an = mpz_size (a); 181 1.1 mrg ap = mpz_limbs_read (a); 182 1.1 mrg bn = mpz_size (b); 183 1.1 mrg bp = mpz_limbs_read (b); 184 1.1 mrg 185 1.1 mrg mpz_add (ref, a, b); 186 1.1 mrg { 187 1.1 mrg mpz_t a1, b1; 188 1.1 mrg #if __STDC_VERSION__ >= 199901 189 1.1 mrg const mpz_t a2 = MPZ_ROINIT_N ( (mp_ptr) ap, an); 190 1.1 mrg const mpz_t b2 = MPZ_ROINIT_N ( (mp_ptr) bp, bn); 191 1.1 mrg 192 1.1 mrg mpz_set_ui (r, 0); 193 1.1 mrg mpz_add (r, a2, b2); 194 1.1 mrg if (mpz_cmp (r, ref) != 0) 195 1.1 mrg { 196 1.1 mrg printf ("MPZ_ROINIT_N failed\n"); 197 1.1 mrg gmp_printf ("a = %Zx\n", a); 198 1.1 mrg gmp_printf ("b = %Zx\n", b); 199 1.1 mrg gmp_printf ("r = %Zx (bad)\n", r); 200 1.1 mrg gmp_printf ("ref = %Zx\n", ref); 201 1.1 mrg abort (); 202 1.1 mrg } 203 1.1 mrg #endif 204 1.1 mrg mpz_set_ui (r, 0); 205 1.1 mrg mpz_add (r, mpz_roinit_n (a1, ap, an), mpz_roinit_n (b1, bp, bn)); 206 1.1 mrg if (mpz_cmp (r, ref) != 0) 207 1.1 mrg { 208 1.1 mrg printf ("mpz_roinit_n failed\n"); 209 1.1 mrg gmp_printf ("a = %Zx\n", a); 210 1.1 mrg gmp_printf ("b = %Zx\n", b); 211 1.1 mrg gmp_printf ("r = %Zx (bad)\n", r); 212 1.1 mrg gmp_printf ("ref = %Zx\n", ref); 213 1.1 mrg abort (); 214 1.1 mrg } 215 1.1 mrg } 216 1.1 mrg } 217 1.1 mrg mpz_clears (bs, a, b, r, ref, NULL); 218 1.1 mrg } 219 1.1 mrg 220 1.1 mrg int 221 1.1 mrg main (int argc, char *argv[]) 222 1.1 mrg { 223 1.1 mrg tests_start (); 224 1.1 mrg tests_end (); 225 1.1 mrg 226 1.1 mrg check_add (); 227 1.1 mrg check_mul (); 228 1.1 mrg check_roinit (); 229 1.1 mrg 230 1.1 mrg return 0; 231 1.1 mrg 232 1.1 mrg } 233