1/* Test for sqrlo function. 2 3Copyright 2009, 2015 Free Software Foundation, Inc. 4 5This file is part of the GNU MP Library test suite. 6 7The GNU MP Library test suite is free software; you can redistribute it 8and/or modify it under the terms of the GNU General Public License as 9published by the Free Software Foundation; either version 3 of the License, 10or (at your option) any later version. 11 12The GNU MP Library test suite is distributed in the hope that it will be 13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 15Public License for more details. 16 17You should have received a copy of the GNU General Public License along with 18the 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-impl.h" 25#include "tests.h" 26 27/* Sizes are up to 2^SIZE_LOG limbs */ 28#ifndef SIZE_LOG 29#define SIZE_LOG 10 30#endif 31 32#ifndef COUNT 33#define COUNT 10000 34#endif 35 36#define MAX_N (1L << SIZE_LOG) 37#define MIN_N (1) 38 39int 40main (int argc, char **argv) 41{ 42 mp_ptr ap, refp, pp, scratch; 43 int count = COUNT; 44 int test; 45 gmp_randstate_ptr rands; 46 TMP_DECL; 47 TMP_MARK; 48 49 TESTS_REPS (count, argv, argc); 50 51 tests_start (); 52 rands = RANDS; 53 54#define mpn_sqrlo_itch(n) (0) 55 56 ap = TMP_ALLOC_LIMBS (MAX_N); 57 refp = TMP_ALLOC_LIMBS (MAX_N * 2); 58 pp = 1+TMP_ALLOC_LIMBS (MAX_N + 2); 59 scratch 60 = 1+TMP_ALLOC_LIMBS (mpn_sqrlo_itch (MAX_N) + 2); 61 62 for (test = 0; test < count; test++) 63 { 64 unsigned size_min; 65 unsigned size_range; 66 mp_size_t n; 67 mp_size_t itch; 68 mp_limb_t p_before, p_after, s_before, s_after; 69 70 for (size_min = 1; (1L << size_min) < MIN_N; size_min++) 71 ; 72 73 /* We generate an in the MIN_N <= n <= (1 << size_range). */ 74 size_range = size_min 75 + gmp_urandomm_ui (rands, SIZE_LOG + 1 - size_min); 76 77 n = MIN_N 78 + gmp_urandomm_ui (rands, (1L << size_range) + 1 - MIN_N); 79 80 mpn_random2 (ap, n); 81 mpn_random2 (pp-1, n + 2); 82 p_before = pp[-1]; 83 p_after = pp[n]; 84 85 itch = mpn_sqrlo_itch (n); 86 ASSERT_ALWAYS (itch <= mpn_sqrlo_itch (MAX_N)); 87 mpn_random2 (scratch-1, itch+2); 88 s_before = scratch[-1]; 89 s_after = scratch[itch]; 90 91 mpn_sqrlo (pp, ap, n); 92 mpn_sqr (refp, ap, n); 93 if (pp[-1] != p_before || pp[n] != p_after 94 || scratch[-1] != s_before || scratch[itch] != s_after 95 || mpn_cmp (refp, pp, n) != 0) 96 { 97 printf ("ERROR in test %d, n = %d", 98 test, (int) n); 99 if (pp[-1] != p_before) 100 { 101 printf ("before pp:"); mpn_dump (pp -1, 1); 102 printf ("keep: "); mpn_dump (&p_before, 1); 103 } 104 if (pp[n] != p_after) 105 { 106 printf ("after pp:"); mpn_dump (pp + n, 1); 107 printf ("keep: "); mpn_dump (&p_after, 1); 108 } 109 if (scratch[-1] != s_before) 110 { 111 printf ("before scratch:"); mpn_dump (scratch-1, 1); 112 printf ("keep: "); mpn_dump (&s_before, 1); 113 } 114 if (scratch[itch] != s_after) 115 { 116 printf ("after scratch:"); mpn_dump (scratch + itch, 1); 117 printf ("keep: "); mpn_dump (&s_after, 1); 118 } 119 mpn_dump (ap, n); 120 mpn_dump (pp, n); 121 mpn_dump (refp, n); 122 123 abort(); 124 } 125 } 126 TMP_FREE; 127 tests_end (); 128 return 0; 129} 130