1/* Test file for mpfr_div_ui. 2 3Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 4Contributed by the Arenaire and Cacao projects, INRIA. 5 6This file is part of the GNU MPFR Library. 7 8The GNU MPFR Library is free software; you can redistribute it and/or modify 9it under the terms of the GNU Lesser General Public License as published by 10the Free Software Foundation; either version 3 of the License, or (at your 11option) any later version. 12 13The GNU MPFR Library is distributed in the hope that it will be useful, but 14WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 16License for more details. 17 18You should have received a copy of the GNU Lesser General Public License 19along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see 20http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 2151 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ 22 23#include <stdio.h> 24#include <stdlib.h> 25#include <float.h> 26 27#include "mpfr-test.h" 28 29static void 30check (const char *ds, unsigned long u, mpfr_rnd_t rnd, const char *es) 31{ 32 mpfr_t x, y; 33 34 mpfr_init2 (x, 53); 35 mpfr_init2 (y, 53); 36 mpfr_set_str1 (x, ds); 37 mpfr_div_ui (y, x, u, rnd); 38 if (mpfr_cmp_str1 (y, es)) 39 { 40 printf ("mpfr_div_ui failed for x=%s, u=%lu, rnd=%s\n", ds, u, 41 mpfr_print_rnd_mode (rnd)); 42 printf ("expected result is %s, got", es); 43 mpfr_out_str(stdout, 10, 0, y, MPFR_RNDN); 44 exit (1); 45 } 46 mpfr_clear (x); 47 mpfr_clear (y); 48} 49 50static void 51special (void) 52{ 53 mpfr_t x, y; 54 unsigned xprec, yprec; 55 56 mpfr_init (x); 57 mpfr_init (y); 58 59 mpfr_set_prec (x, 32); 60 mpfr_set_prec (y, 32); 61 mpfr_set_ui (x, 1, MPFR_RNDN); 62 mpfr_div_ui (y, x, 3, MPFR_RNDN); 63 64 mpfr_set_prec (x, 100); 65 mpfr_set_prec (y, 100); 66 mpfr_urandomb (x, RANDS); 67 mpfr_div_ui (y, x, 123456, MPFR_RNDN); 68 mpfr_set_ui (x, 0, MPFR_RNDN); 69 mpfr_div_ui (y, x, 123456789, MPFR_RNDN); 70 if (mpfr_cmp_ui (y, 0)) 71 { 72 printf ("mpfr_div_ui gives non-zero for 0/ui\n"); 73 exit (1); 74 } 75 76 /* bug found by Norbert Mueller, 21 Aug 2001 */ 77 mpfr_set_prec (x, 110); 78 mpfr_set_prec (y, 60); 79 mpfr_set_str_binary (x, "0.110101110011111110011111001110011001110111000000111110001000111011000011E-44"); 80 mpfr_div_ui (y, x, 17, MPFR_RNDN); 81 mpfr_set_str_binary (x, "0.11001010100101100011101110000001100001010110101001010011011E-48"); 82 if (mpfr_cmp (x, y)) 83 { 84 printf ("Error in x/17 for x=1/16!\n"); 85 printf ("Expected "); 86 mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); 87 printf ("\nGot "); 88 mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); 89 printf ("\n"); 90 exit (1); 91 } 92 93 /* corner case */ 94 mpfr_set_prec (x, 2 * mp_bits_per_limb); 95 mpfr_set_prec (y, 2); 96 mpfr_set_ui (x, 4, MPFR_RNDN); 97 mpfr_nextabove (x); 98 mpfr_div_ui (y, x, 2, MPFR_RNDN); /* exactly in the middle */ 99 MPFR_ASSERTN(mpfr_cmp_ui (y, 2) == 0); 100 101 mpfr_set_prec (x, 3 * mp_bits_per_limb); 102 mpfr_set_prec (y, 2); 103 mpfr_set_ui (x, 2, MPFR_RNDN); 104 mpfr_nextabove (x); 105 mpfr_div_ui (y, x, 2, MPFR_RNDN); 106 MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0); 107 108 mpfr_set_prec (x, 3 * mp_bits_per_limb); 109 mpfr_set_prec (y, 2); 110 mpfr_set_si (x, -4, MPFR_RNDN); 111 mpfr_nextbelow (x); 112 mpfr_div_ui (y, x, 2, MPFR_RNDD); 113 MPFR_ASSERTN(mpfr_cmp_si (y, -3) == 0); 114 115 for (xprec = 53; xprec <= 128; xprec++) 116 { 117 mpfr_set_prec (x, xprec); 118 mpfr_set_str_binary (x, "0.1100100100001111110011111000000011011100001100110111E2"); 119 for (yprec = 53; yprec <= 128; yprec++) 120 { 121 mpfr_set_prec (y, yprec); 122 mpfr_div_ui (y, x, 1, MPFR_RNDN); 123 if (mpfr_cmp(x,y)) 124 { 125 printf ("division by 1.0 fails for xprec=%u, yprec=%u\n", xprec, yprec); 126 printf ("expected "); mpfr_print_binary (x); puts (""); 127 printf ("got "); mpfr_print_binary (y); puts (""); 128 exit (1); 129 } 130 } 131 } 132 133 /* Bug reported by Mark Dickinson, 6 Nov 2007 */ 134 mpfr_set_si (x, 0, MPFR_RNDN); 135 mpfr_set_si (y, -1, MPFR_RNDN); 136 mpfr_div_ui (y, x, 4, MPFR_RNDN); 137 MPFR_ASSERTN(MPFR_IS_ZERO(y) && MPFR_IS_POS(y)); 138 139 mpfr_clear (x); 140 mpfr_clear (y); 141} 142 143static void 144check_inexact (void) 145{ 146 mpfr_t x, y, z; 147 mpfr_prec_t px, py; 148 int inexact, cmp; 149 unsigned long int u; 150 int rnd; 151 152 mpfr_init (x); 153 mpfr_init (y); 154 mpfr_init (z); 155 156 for (px=2; px<300; px++) 157 { 158 mpfr_set_prec (x, px); 159 mpfr_urandomb (x, RANDS); 160 do 161 { 162 u = randlimb (); 163 } 164 while (u == 0); 165 for (py=2; py<300; py++) 166 { 167 mpfr_set_prec (y, py); 168 mpfr_set_prec (z, py + mp_bits_per_limb); 169 for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) 170 { 171 inexact = mpfr_div_ui (y, x, u, (mpfr_rnd_t) rnd); 172 if (mpfr_mul_ui (z, y, u, (mpfr_rnd_t) rnd)) 173 { 174 printf ("z <- y * u should be exact for u=%lu\n", u); 175 printf ("y="); mpfr_print_binary (y); puts (""); 176 printf ("z="); mpfr_print_binary (z); puts (""); 177 exit (1); 178 } 179 cmp = mpfr_cmp (z, x); 180 if (((inexact == 0) && (cmp != 0)) || 181 ((inexact > 0) && (cmp <= 0)) || 182 ((inexact < 0) && (cmp >= 0))) 183 { 184 printf ("Wrong inexact flag for u=%lu, rnd=%s\n", u, 185 mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 186 printf ("x="); mpfr_print_binary (x); puts (""); 187 printf ("y="); mpfr_print_binary (y); puts (""); 188 exit (1); 189 } 190 } 191 } 192 } 193 194 mpfr_clear (x); 195 mpfr_clear (y); 196 mpfr_clear (z); 197} 198 199#define TEST_FUNCTION mpfr_div_ui 200#define INTEGER_TYPE unsigned long 201#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS) 202#include "tgeneric_ui.c" 203 204int 205main (int argc, char **argv) 206{ 207 mpfr_t x; 208 209 tests_start_mpfr (); 210 211 special (); 212 213 check_inexact (); 214 215 check("1.0", 3, MPFR_RNDN, "3.3333333333333331483e-1"); 216 check("1.0", 3, MPFR_RNDZ, "3.3333333333333331483e-1"); 217 check("1.0", 3, MPFR_RNDU, "3.3333333333333337034e-1"); 218 check("1.0", 3, MPFR_RNDD, "3.3333333333333331483e-1"); 219 check("1.0", 2116118, MPFR_RNDN, "4.7256343927890600483e-7"); 220 check("1.098612288668109782", 5, MPFR_RNDN, "0.21972245773362195087"); 221 222 mpfr_init2 (x, 53); 223 mpfr_set_ui (x, 3, MPFR_RNDD); 224 mpfr_log (x, x, MPFR_RNDD); 225 mpfr_div_ui (x, x, 5, MPFR_RNDD); 226 if (mpfr_cmp_str1 (x, "0.21972245773362189536")) 227 { 228 printf ("Error in mpfr_div_ui for x=ln(3), u=5\n"); 229 exit (1); 230 } 231 mpfr_clear (x); 232 233 test_generic_ui (2, 200, 100); 234 235 tests_end_mpfr (); 236 return 0; 237} 238