github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/mpn/toom-shared.h (about) 1 /* Test for various Toom functions. 2 3 Copyright 2009 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 21 #include <stdlib.h> 22 #include <stdio.h> 23 24 #include "gmp.h" 25 #include "gmp-impl.h" 26 #include "tests.h" 27 28 /* Main file is expected to define mpn_toomMN_mul, 29 * mpn_toomMN_mul_itch, MIN_AN, MIN_BN(an), MAX_BN(an) and then 30 * include this file. */ 31 32 /* Sizes are up to 2^SIZE_LOG limbs */ 33 #ifndef SIZE_LOG 34 #define SIZE_LOG 10 35 #endif 36 37 #ifndef COUNT 38 #define COUNT 2000 39 #endif 40 41 #define MAX_AN (1L << SIZE_LOG) 42 43 #ifndef MAX_BN 44 #define MAX_BN(an) (an) 45 #endif 46 47 /* For general toomMN_mul, we need 48 * 49 * MIN_BN(an) = N + floor(((N-1)*an + M - N)/M) 50 * 51 * MAX_BN(an) = floor(N*(an-1)/(M-1)) - N + 1 52 */ 53 54 int 55 main (int argc, char **argv) 56 { 57 mp_ptr ap, bp, refp, pp, scratch; 58 int count = COUNT; 59 int test; 60 gmp_randstate_ptr rands; 61 TMP_DECL; 62 TMP_MARK; 63 64 if (argc > 1) 65 { 66 char *end; 67 count = strtol (argv[1], &end, 0); 68 if (*end || count <= 0) 69 { 70 fprintf (stderr, "Invalid test count: %s.\n", argv[1]); 71 return 1; 72 } 73 } 74 75 tests_start (); 76 rands = RANDS; 77 78 ap = TMP_ALLOC_LIMBS (MAX_AN); 79 bp = TMP_ALLOC_LIMBS (MAX_BN(MAX_AN)); 80 refp = TMP_ALLOC_LIMBS (MAX_AN + MAX_BN(MAX_AN)); 81 pp = 1+TMP_ALLOC_LIMBS (MAX_AN + MAX_BN(MAX_AN)+2); 82 scratch 83 = 1+TMP_ALLOC_LIMBS (mpn_toomMN_mul_itch (MAX_AN, MAX_BN(MAX_AN)) 84 + 2); 85 86 for (test = 0; test < count; test++) 87 { 88 unsigned size_min; 89 unsigned size_range; 90 mp_size_t an, bn; 91 mp_size_t itch; 92 mp_limb_t p_before, p_after, s_before, s_after; 93 94 for (size_min = 1; (1L << size_min) < MIN_AN; size_min++) 95 ; 96 97 /* We generate an in the MIN_AN <= an <= (1 << size_range). */ 98 size_range = size_min 99 + gmp_urandomm_ui (rands, SIZE_LOG + 1 - size_min); 100 101 an = MIN_AN 102 + gmp_urandomm_ui (rands, (1L << size_range) + 1 - MIN_AN); 103 bn = MIN_BN(an) 104 + gmp_urandomm_ui (rands, MAX_BN(an) + 1 - MIN_BN(an)); 105 106 mpn_random2 (ap, an); 107 mpn_random2 (bp, bn); 108 mpn_random2 (pp-1, an + bn + 2); 109 p_before = pp[-1]; 110 p_after = pp[an + bn]; 111 112 itch = mpn_toomMN_mul_itch (an, bn); 113 ASSERT_ALWAYS (itch <= mpn_toomMN_mul_itch (MAX_AN, MAX_BN(MAX_AN))); 114 mpn_random2 (scratch-1, itch+2); 115 s_before = scratch[-1]; 116 s_after = scratch[itch]; 117 118 mpn_toomMN_mul (pp, ap, an, bp, bn, scratch); 119 refmpn_mul (refp, ap, an, bp, bn); 120 if (pp[-1] != p_before || pp[an + bn] != p_after 121 || scratch[-1] != s_before || scratch[itch] != s_after 122 || mpn_cmp (refp, pp, an + bn) != 0) 123 { 124 printf ("ERROR in test %d, an = %d, bn = %d\n", 125 test, (int) an, (int) bn); 126 if (pp[-1] != p_before) 127 { 128 printf ("before pp:"); mpn_dump (pp -1, 1); 129 printf ("keep: "); mpn_dump (&p_before, 1); 130 } 131 if (pp[an + bn] != p_after) 132 { 133 printf ("after pp:"); mpn_dump (pp + an + bn, 1); 134 printf ("keep: "); mpn_dump (&p_after, 1); 135 } 136 if (scratch[-1] != s_before) 137 { 138 printf ("before scratch:"); mpn_dump (scratch-1, 1); 139 printf ("keep: "); mpn_dump (&s_before, 1); 140 } 141 if (scratch[itch] != s_after) 142 { 143 printf ("after scratch:"); mpn_dump (scratch + itch, 1); 144 printf ("keep: "); mpn_dump (&s_after, 1); 145 } 146 mpn_dump (ap, an); 147 mpn_dump (bp, bn); 148 mpn_dump (pp, an + bn); 149 mpn_dump (refp, an + bn); 150 151 abort(); 152 } 153 } 154 TMP_FREE; 155 156 tests_end (); 157 return 0; 158 }