github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/mpn/t-divrem_1.c (about) 1 /* Test mpn_divrem_1 and mpn_preinv_divrem_1. 2 3 Copyright 2003 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 <stdio.h> 21 #include <stdlib.h> 22 23 #include "gmp.h" 24 #include "gmp-impl.h" 25 #include "tests.h" 26 27 28 void 29 check_data (void) 30 { 31 static const struct { 32 mp_limb_t n[1]; 33 mp_size_t nsize; 34 mp_limb_t d; 35 mp_size_t qxn; 36 mp_limb_t want_q[5]; 37 mp_limb_t want_r; 38 } data[] = { 39 { { 0 }, 1, 1, 0, 40 { 0 }, 0}, 41 42 { { 5 }, 1, 2, 0, 43 { 2 }, 1}, 44 45 /* Exercises the q update in the nl == constant 0 case of 46 udiv_qrnnd_preinv3. Test case copied from t-fat.c. */ 47 { { 287 }, 1, 7, 1, 48 { 0, 41 }, 0 }, 49 50 #if GMP_NUMB_BITS == 32 51 { { 0x3C }, 1, 0xF2, 1, 52 { 0x3F789854, 0 }, 0x98 }, 53 #endif 54 55 #if GMP_NUMB_BITS == 64 56 { { 0x3C }, 1, 0xF2, 1, 57 { CNST_LIMB(0x3F789854A0CB1B81), 0 }, 0x0E }, 58 59 /* This case exposed some wrong code generated by SGI cc on mips64 irix 60 6.5 with -n32 -O2, in the fractional loop for normalized divisor 61 using udiv_qrnnd_preinv. A test "x>al" in one of the sub_ddmmss 62 expansions came out wrong, leading to an incorrect quotient. */ 63 { { CNST_LIMB(0x3C00000000000000) }, 1, CNST_LIMB(0xF200000000000000), 1, 64 { CNST_LIMB(0x3F789854A0CB1B81), 0 }, CNST_LIMB(0x0E00000000000000) }, 65 #endif 66 }; 67 68 mp_limb_t dinv, got_r, got_q[numberof(data[0].want_q)]; 69 mp_size_t qsize; 70 int i, shift; 71 72 for (i = 0; i < numberof (data); i++) 73 { 74 qsize = data[i].nsize + data[i].qxn; 75 ASSERT_ALWAYS (qsize <= numberof (got_q)); 76 77 got_r = mpn_divrem_1 (got_q, data[i].qxn, data[i].n, data[i].nsize, 78 data[i].d); 79 if (got_r != data[i].want_r 80 || refmpn_cmp (got_q, data[i].want_q, qsize) != 0) 81 { 82 printf ("mpn_divrem_1 wrong at data[%d]\n", i); 83 bad: 84 mpn_trace (" n", data[i].n, data[i].nsize); 85 printf (" nsize=%ld\n", (long) data[i].nsize); 86 mp_limb_trace (" d", data[i].d); 87 printf (" qxn=%ld\n", (long) data[i].qxn); 88 mpn_trace (" want q", data[i].want_q, qsize); 89 mpn_trace (" got q", got_q, qsize); 90 mp_limb_trace (" want r", data[i].want_r); 91 mp_limb_trace (" got r", got_r); 92 abort (); 93 } 94 95 /* test if available */ 96 #if USE_PREINV_DIVREM_1 || HAVE_NATIVE_mpn_preinv_divrem_1 97 shift = refmpn_count_leading_zeros (data[i].d); 98 dinv = refmpn_invert_limb (data[i].d << shift); 99 got_r = mpn_preinv_divrem_1 (got_q, data[i].qxn, 100 data[i].n, data[i].nsize, 101 data[i].d, dinv, shift); 102 if (got_r != data[i].want_r 103 || refmpn_cmp (got_q, data[i].want_q, qsize) != 0) 104 { 105 printf ("mpn_preinv divrem_1 wrong at data[%d]\n", i); 106 printf (" shift=%d\n", shift); 107 mp_limb_trace (" dinv", dinv); 108 goto bad; 109 } 110 #endif 111 } 112 } 113 114 int 115 main (void) 116 { 117 tests_start (); 118 mp_trace_base = -16; 119 120 check_data (); 121 122 tests_end (); 123 exit (0); 124 }