1 /* Test file for mpfr_div_ui. 2 3 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. 4 Contributed by the AriC and Caramel projects, INRIA. 5 6 This file is part of the GNU MPFR Library. 7 8 The GNU MPFR Library is free software; you can redistribute it and/or modify 9 it under the terms of the GNU Lesser General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or (at your 11 option) any later version. 12 13 The GNU MPFR Library is distributed in the hope that it will be useful, but 14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 16 License for more details. 17 18 You should have received a copy of the GNU Lesser General Public License 19 along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see 20 http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 21 51 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 29 static void 30 check (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 50 static void 51 special (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 143 static void 144 check_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 204 int 205 main (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