1/* Test mpf_div. 2 3Copyright 2004 Free Software Foundation, Inc. 4 5This file is part of the GNU MP Library. 6 7The GNU MP Library is free software; you can redistribute it and/or modify 8it under the terms of the GNU Lesser General Public License as published by 9the Free Software Foundation; either version 3 of the License, or (at your 10option) any later version. 11 12The GNU MP Library is distributed in the hope that it will be useful, but 13WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15License for more details. 16 17You should have received a copy of the GNU Lesser General Public License 18along with the GNU MP Library. If not, see http://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 27void 28check_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 40void 41check_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) */ 104void 105check_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 144void 145check_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 175int 176main (void) 177{ 178 tests_start (); 179 180 check_various (); 181 check_rand (); 182 check_reuse_three (); 183 184 tests_end (); 185 exit (0); 186} 187