1/* Test mpf_ui_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, unsigned long u, mpf_srcptr v) 29{ 30 mpf_t uf; 31 mp_limb_t ulimbs[2]; 32 mp_size_t usize; 33 34 ulimbs[0] = u & GMP_NUMB_MASK; 35 usize = (u != 0); 36#if BITS_PER_ULONG > GMP_NUMB_BITS 37 u >>= GMP_NUMB_BITS; 38 ulimbs[1] = u; 39 usize += (u != 0); 40#endif 41 PTR(uf) = ulimbs; 42 SIZ(uf) = usize; 43 EXP(uf) = usize; 44 45 if (! refmpf_validate_division ("mpf_ui_div", got, uf, v)) 46 { 47 mp_trace_base = -16; 48 printf (" u 0x%lX (%lu)\n", u, u); 49 mpf_trace (" v", v); 50 printf (" %s\n", desc); 51 abort (); 52 } 53} 54 55void 56check_rand (void) 57{ 58 unsigned long min_prec = __GMPF_BITS_TO_PREC (1); 59 gmp_randstate_ptr rands = RANDS; 60 unsigned long prec, u; 61 mpf_t got, v; 62 int i; 63 64 mpf_init (got); 65 mpf_init (v); 66 67 for (i = 0; i < 200; i++) 68 { 69 /* got precision */ 70 prec = min_prec + gmp_urandomm_ui (rands, 15L); 71 refmpf_set_prec_limbs (got, prec); 72 73 /* u */ 74 prec = gmp_urandomm_ui (rands, BITS_PER_ULONG+1); 75 u = gmp_urandomb_ui (rands, prec); 76 77 /* v precision */ 78 prec = min_prec + gmp_urandomm_ui (rands, 15L); 79 refmpf_set_prec_limbs (v, prec); 80 81 /* v, non-zero */ 82 do { 83 mpf_random2 (v, PREC(v), (mp_exp_t) 20); 84 } while (SIZ(v) == 0); 85 86 /* v possibly negative */ 87 if (gmp_urandomb_ui (rands, 1L)) 88 mpf_neg (v, v); 89 90 if ((i % 2) == 0) 91 { 92 /* src != dst */ 93 mpf_ui_div (got, u, v); 94 check_one ("separate", got, u, v); 95 } 96 else 97 { 98 /* src == dst */ 99 prec = refmpf_set_overlap (got, v); 100 mpf_ui_div (got, u, got); 101 check_one ("overlap src==dst", got, u, v); 102 103 mpf_set_prec_raw (got, prec); 104 } 105 } 106 107 mpf_clear (got); 108 mpf_clear (v); 109} 110 111void 112check_various (void) 113{ 114 mpf_t got, v; 115 116 mpf_init (got); 117 mpf_init (v); 118 119 /* 100/4 == 25 */ 120 mpf_set_prec (got, 20L); 121 mpf_set_ui (v, 4L); 122 mpf_ui_div (got, 100L, v); 123 MPF_CHECK_FORMAT (got); 124 ASSERT_ALWAYS (mpf_cmp_ui (got, 25L) == 0); 125 126 { 127 /* 1/(2^n+1), a case where truncating the divisor would be wrong */ 128 unsigned long u = 1L; 129 mpf_set_prec (got, 500L); 130 mpf_set_prec (v, 900L); 131 mpf_set_ui (v, 1L); 132 mpf_mul_2exp (v, v, 800L); 133 mpf_add_ui (v, v, 1L); 134 mpf_ui_div (got, u, v); 135 check_one ("1/2^n+1, separate", got, u, v); 136 } 137 138 mpf_clear (got); 139 mpf_clear (v); 140} 141 142int 143main (void) 144{ 145 tests_start (); 146 147 check_various (); 148 check_rand (); 149 150 tests_end (); 151 exit (0); 152} 153