github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/mpf/t-div.c (about) 1 /* Test mpf_div. 2 3 Copyright 2004 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 #include "gmp.h" 23 #include "gmp-impl.h" 24 #include "tests.h" 25 26 27 void 28 check_one (const char *desc, mpf_ptr got, mpf_srcptr u, mpf_srcptr v) 29 { 30 if (! refmpf_validate_division ("mpf_div", got, u, v)) 31 { 32 mp_trace_base = -16; 33 mpf_trace (" u", u); 34 mpf_trace (" v", v); 35 printf (" %s\n", desc); 36 abort (); 37 } 38 } 39 40 void 41 check_rand (void) 42 { 43 unsigned long min_prec = __GMPF_BITS_TO_PREC (1); 44 gmp_randstate_ptr rands = RANDS; 45 unsigned long prec; 46 mpf_t got, u, v; 47 int i; 48 49 mpf_init (got); 50 mpf_init (u); 51 mpf_init (v); 52 53 /* separate */ 54 for (i = 0; i < 100; i++) 55 { 56 /* got precision */ 57 prec = min_prec + gmp_urandomm_ui (rands, 15L); 58 refmpf_set_prec_limbs (got, prec); 59 60 /* u */ 61 prec = min_prec + gmp_urandomm_ui (rands, 15L); 62 refmpf_set_prec_limbs (u, prec); 63 do { 64 mpf_random2 (u, PREC(u), (mp_exp_t) 20); 65 } while (SIZ(u) == 0); 66 if (gmp_urandomb_ui (rands, 1L)) 67 mpf_neg (u, u); 68 69 /* v */ 70 prec = min_prec + gmp_urandomm_ui (rands, 15L); 71 refmpf_set_prec_limbs (v, prec); 72 do { 73 mpf_random2 (v, PREC(v), (mp_exp_t) 20); 74 } while (SIZ(v) == 0); 75 if (gmp_urandomb_ui (rands, 1L)) 76 mpf_neg (v, v); 77 78 switch (i % 3) { 79 case 0: 80 mpf_div (got, u, v); 81 check_one ("separate", got, u, v); 82 break; 83 case 1: 84 prec = refmpf_set_overlap (got, u); 85 mpf_div (got, got, v); 86 check_one ("dst == u", got, u, v); 87 mpf_set_prec_raw (got, prec); 88 break; 89 case 2: 90 prec = refmpf_set_overlap (got, v); 91 mpf_div (got, u, got); 92 check_one ("dst == v", got, u, v); 93 mpf_set_prec_raw (got, prec); 94 break; 95 } 96 } 97 98 mpf_clear (got); 99 mpf_clear (u); 100 mpf_clear (v); 101 } 102 103 /* Exercise calls mpf(x,x,x) */ 104 void 105 check_reuse_three (void) 106 { 107 unsigned long min_prec = __GMPF_BITS_TO_PREC (1); 108 gmp_randstate_ptr rands = RANDS; 109 unsigned long result_prec, input_prec, set_prec; 110 mpf_t got; 111 int i; 112 113 mpf_init (got); 114 115 for (i = 0; i < 8; i++) 116 { 117 result_prec = min_prec + gmp_urandomm_ui (rands, 15L); 118 input_prec = min_prec + gmp_urandomm_ui (rands, 15L); 119 120 set_prec = MAX (result_prec, input_prec); 121 refmpf_set_prec_limbs (got, set_prec); 122 123 /* input, non-zero, possibly negative */ 124 PREC(got) = input_prec; 125 do { 126 mpf_random2 (got, input_prec, (mp_exp_t) 20); 127 } while (SIZ(got) == 0); 128 if (gmp_urandomb_ui (rands, 1L)) 129 mpf_neg (got, got); 130 131 PREC(got) = result_prec; 132 133 mpf_div (got, got, got); 134 135 /* expect exactly 1.0 always */ 136 ASSERT_ALWAYS (mpf_cmp_ui (got, 1L) == 0); 137 138 PREC(got) = set_prec; 139 } 140 141 mpf_clear (got); 142 } 143 144 void 145 check_various (void) 146 { 147 mpf_t got, u, v; 148 149 mpf_init (got); 150 mpf_init (u); 151 mpf_init (v); 152 153 /* 100/4 == 25 */ 154 mpf_set_prec (got, 20L); 155 mpf_set_ui (u, 100L); 156 mpf_set_ui (v, 4L); 157 mpf_div (got, u, v); 158 MPF_CHECK_FORMAT (got); 159 ASSERT_ALWAYS (mpf_cmp_ui (got, 25L) == 0); 160 161 /* 1/(2^n+1), a case where truncating the divisor would be wrong */ 162 mpf_set_prec (got, 500L); 163 mpf_set_prec (v, 900L); 164 mpf_set_ui (v, 1L); 165 mpf_mul_2exp (v, v, 800L); 166 mpf_add_ui (v, v, 1L); 167 mpf_div (got, u, v); 168 check_one ("1/2^n+1, separate", got, u, v); 169 170 mpf_clear (got); 171 mpf_clear (u); 172 mpf_clear (v); 173 } 174 175 int 176 main (void) 177 { 178 tests_start (); 179 180 check_various (); 181 check_rand (); 182 check_reuse_three (); 183 184 tests_end (); 185 exit (0); 186 }