tfrac.c revision 1.1.1.1
1/* Test file for mpfr_frac. 2 3Copyright 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 26#include "mpfr-test.h" 27 28#define PIP 70 29#define PFP 70 30#define PMAX (PIP+2*PFP) 31 32static void 33check0 (mpfr_ptr ip, mpfr_ptr fp, mpfr_prec_t prec, mpfr_rnd_t rnd) 34{ 35 mpfr_t sum, tmp, dst, fp2; 36 int inex1, inex2; 37 38 mpfr_init2 (sum, PMAX); 39 mpfr_init2 (tmp, PMAX); 40 mpfr_init2 (dst, prec); 41 mpfr_init2 (fp2, prec); 42 43 if (MPFR_SIGN (ip) != MPFR_SIGN (fp)) 44 { 45 printf ("Internal error (1)\n"); 46 exit (1); 47 } 48 if (mpfr_add (sum, ip, fp, MPFR_RNDZ)) 49 { 50 printf ("Wrong inexact flag in mpfr_add\n"); 51 exit (1); 52 } 53 if (MPFR_SIGN (sum) != MPFR_SIGN (fp)) 54 { 55 printf ("Internal error (2)\n"); 56 exit (1); 57 } 58 59 inex1 = mpfr_frac (dst, sum, rnd); 60 inex2 = mpfr_set (fp2, fp, rnd); 61 if (inex1 != inex2) 62 { 63 printf ("Wrong inexact flag in mpfr_frac for\n"); 64 mpfr_out_str (stdout, 2, 0, sum, MPFR_RNDN); 65 printf ("\nGot %d instead of %d\n", inex1, inex2); 66 exit (1); 67 } 68 if (!mpfr_number_p (dst) || 69 MPFR_SIGN (dst) != MPFR_SIGN (fp2) || 70 mpfr_cmp (dst, fp2)) 71 { 72 printf ("Error in mpfr_frac (y, x, %s) with\nx = ", 73 mpfr_print_rnd_mode (rnd)); 74 mpfr_out_str (stdout, 2, 0, sum, MPFR_RNDN); 75 printf ("\nGot "); 76 mpfr_out_str (stdout, 2, 0, dst, MPFR_RNDN); 77 printf ("\ninstead of "); 78 mpfr_out_str (stdout, 2, 0, fp2, MPFR_RNDN); 79 printf ("\n"); 80 exit (1); 81 } 82 83 if (prec == PMAX) 84 { 85 inex1 = mpfr_frac (sum, sum, rnd); 86 if (inex1) 87 { 88 printf ("Wrong inexact flag in mpfr_frac\n"); 89 exit (1); 90 } 91 if (!mpfr_number_p (sum) || 92 MPFR_SIGN (sum) != MPFR_SIGN (fp) || 93 mpfr_cmp (sum, fp)) 94 { 95 printf ("Error in mpfr_frac (x, x, %s) with\nx = ", 96 mpfr_print_rnd_mode (rnd)); 97 mpfr_add (tmp, ip, fp, MPFR_RNDZ); 98 mpfr_out_str (stdout, 2, 0, tmp, MPFR_RNDN); 99 printf ("\nGot "); 100 mpfr_out_str (stdout, 2, 0, sum, MPFR_RNDN); 101 printf ("\ninstead of "); 102 mpfr_out_str (stdout, 2, 0, fp, MPFR_RNDN); 103 printf ("\n"); 104 exit (1); 105 } 106 } 107 108 mpfr_clear (fp2); 109 mpfr_clear (dst); 110 mpfr_clear (tmp); 111 mpfr_clear (sum); 112} 113 114static void 115check1 (mpfr_ptr ip, mpfr_ptr fp) 116{ 117 int rnd; 118 119 for (rnd = 0; rnd < MPFR_RND_MAX ; rnd++) 120 { 121 check0 (ip, fp, PMAX, (mpfr_rnd_t) rnd); 122 check0 (ip, fp, 70, (mpfr_rnd_t) rnd); 123 mpfr_neg (fp, fp, MPFR_RNDN); 124 mpfr_neg (ip, ip, MPFR_RNDN); 125 check0 (ip, fp, PMAX, (mpfr_rnd_t) rnd); 126 check0 (ip, fp, 70, (mpfr_rnd_t) rnd); 127 mpfr_neg (fp, fp, MPFR_RNDN); 128 mpfr_neg (ip, ip, MPFR_RNDN); 129 } 130} 131 132static void 133special (void) 134{ 135 mpfr_t z, t; 136 137 mpfr_init (z); 138 mpfr_init (t); 139 140 mpfr_set_nan (z); 141 mpfr_frac (t, z, MPFR_RNDN); 142 if (!mpfr_nan_p (t)) 143 { 144 printf ("Error for frac(NaN)\n"); 145 exit (1); 146 } 147 148 mpfr_set_prec (z, 6); 149 mpfr_set_prec (t, 3); 150 151 mpfr_set_str_binary (z, "0.101101E3"); 152 mpfr_frac (t, z, MPFR_RNDN); 153 mpfr_set_str_binary (z, "0.101"); 154 if (mpfr_cmp (t, z)) 155 { 156 printf ("Error in frac(0.101101E3)\n"); 157 exit (1); 158 } 159 160 mpfr_set_prec (z, 34); 161 mpfr_set_prec (t, 26); 162 mpfr_set_str_binary (z, "0.101101010000010011110011001101E9"); 163 mpfr_frac (t, z, MPFR_RNDN); 164 mpfr_set_str_binary (z, "0.000010011110011001101"); 165 if (mpfr_cmp (t, z)) 166 { 167 printf ("Error in frac(0.101101010000010011110011001101E9)\n"); 168 exit (1); 169 } 170 171 mpfr_clear (z); 172 mpfr_clear (t); 173} 174 175static void 176bug20090918 (void) 177{ 178 mpfr_t x, y, z; 179 mp_limb_t y0; 180 int inexy, inexz; 181 int r, i; 182 char *s[] = { "61680.352935791015625", "61680.999999" }; 183 mpfr_exp_t emin; 184 185 emin = mpfr_get_emin (); 186 mpfr_init2 (x, 32); 187 mpfr_init2 (y, 13); 188 189 for (i = 0; i <= 9; i++) 190 { 191 mpfr_set_str (x, s[i & 1], 10, MPFR_RNDZ); 192 193 RND_LOOP(r) 194 { 195 set_emin ((i >> 1) - 3); 196 inexy = mpfr_frac (y, x, (mpfr_rnd_t) r); 197 set_emin (emin); 198 y0 = MPFR_MANT(y)[0]; 199 while (y0 != 0 && (y0 >> 1) << 1 == y0) 200 y0 >>= 1; 201 if (y0 > 0x2000) 202 { 203 printf ("Error in bug20090918 (significand has more than" 204 " 13 bits), i = %d, %s.\n", i, 205 mpfr_print_rnd_mode ((mpfr_rnd_t) r)); 206 exit (1); 207 } 208 mpfr_init2 (z, 32); 209 inexz = mpfr_frac (z, x, MPFR_RNDN); 210 MPFR_ASSERTN (inexz == 0); /* exact */ 211 inexz = mpfr_prec_round (z, 13, (mpfr_rnd_t) r); 212 set_emin ((i >> 1) - 3); 213 inexz = mpfr_check_range (z, inexz, (mpfr_rnd_t) r); 214 set_emin (emin); 215 if (mpfr_cmp0 (y, z) != 0) 216 { 217 printf ("Error in bug20090918, i = %d, %s.\n", i, 218 mpfr_print_rnd_mode ((mpfr_rnd_t) r)); 219 printf ("Expected "); 220 mpfr_dump (z); 221 printf ("Got "); 222 mpfr_dump (y); 223 exit (1); 224 } 225 if (! SAME_SIGN (inexy, inexz)) 226 { 227 printf ("Incorrect ternary value in bug20090918, i = %d, %s.\n", 228 i, mpfr_print_rnd_mode ((mpfr_rnd_t) r)); 229 printf ("Expected %d, got %d.\n", inexz, inexy); 230 exit (1); 231 } 232 mpfr_clear (z); 233 } 234 } 235 236 mpfr_clear (x); 237 mpfr_clear (y); 238} 239 240#define TEST_FUNCTION mpfr_frac 241#include "tgeneric.c" 242 243int 244main (void) 245{ 246 mpfr_t ip, fp; 247 int ni, nf1, nf2; 248 249 tests_start_mpfr (); 250 251 special (); 252 253 mpfr_init2 (ip, PIP); 254 mpfr_init2 (fp, PFP); 255 256 for (ni = -1; ni < PIP; ni++) 257 { 258 if (ni <= 0) 259 { /* ni + 1 */ 260 mpfr_set_si (ip, ni, MPFR_RNDN); 261 mpfr_add_ui (ip, ip, 1, MPFR_RNDN); 262 } 263 else 264 { /* 2^ni + 1 */ 265 mpfr_set_ui (ip, 1, MPFR_RNDN); 266 mpfr_mul_2ui (ip, ip, ni, MPFR_RNDN); 267 mpfr_add_ui (ip, ip, 1, MPFR_RNDN); 268 } 269 270 mpfr_set_ui (fp, 0, MPFR_RNDN); 271 check1 (ip, fp); 272 273 for (nf1 = 1; nf1 < PFP; nf1++) 274 { 275 mpfr_set_ui (fp, 1, MPFR_RNDN); 276 mpfr_div_2ui (fp, fp, nf1, MPFR_RNDN); 277 check1 (ip, fp); 278 nf2 = 1 + (randlimb () % (PFP - 1)); 279 mpfr_set_ui (fp, 1, MPFR_RNDN); 280 mpfr_div_2ui (fp, fp, nf2, MPFR_RNDN); 281 mpfr_add_ui (fp, fp, 1, MPFR_RNDN); 282 mpfr_div_2ui (fp, fp, nf1, MPFR_RNDN); 283 check1 (ip, fp); 284 } 285 } 286 287 mpfr_set_ui (ip, 1, MPFR_RNDN); 288 mpfr_div_ui (ip, ip, 0, MPFR_RNDN); 289 mpfr_set_ui (fp, 0, MPFR_RNDN); 290 check1 (ip, fp); /* test infinities */ 291 292 mpfr_clear (ip); 293 mpfr_clear (fp); 294 295 bug20090918 (); 296 297 test_generic (2, 1000, 10); 298 299 tests_end_mpfr (); 300 return 0; 301} 302