1/* Test file for mpfr_set_z_2exp. 2 3Copyright 1999, 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 <limits.h> 26 27#include "mpfr-test.h" 28 29static mpfr_exp_t 30randexp (void) 31{ 32 return (mpfr_exp_t) (randlimb () % (__gmpfr_emax - __gmpfr_emin)) 33 + __gmpfr_emin; 34} 35 36static void 37check0 (void) 38{ 39 mpz_t y; 40 mpfr_t x; 41 int inexact, r; 42 mpfr_exp_t e; 43 44 /* Check for +0 */ 45 mpfr_init (x); 46 mpz_init (y); 47 mpz_set_si (y, 0); 48 for (r = 0; r < MPFR_RND_MAX; r++) 49 { 50 e = randexp (); 51 inexact = mpfr_set_z_2exp (x, y, e, (mpfr_rnd_t) r); 52 if (!MPFR_IS_ZERO(x) || !MPFR_IS_POS(x) || inexact) 53 { 54 printf ("mpfr_set_z_2exp(x,0,e) failed for e=%ld, rnd=%s\n", e, 55 mpfr_print_rnd_mode ((mpfr_rnd_t) r)); 56 exit (1); 57 } 58 } 59 mpfr_clear(x); 60 mpz_clear(y); 61} 62 63/* FIXME: It'd be better to examine the actual data in an mpfr_t to see that 64 it's as expected. Comparing mpfr_set_z with mpfr_cmp or against 65 mpfr_get_si is a rather indirect test of a low level routine. */ 66 67static void 68check (long i, mpfr_rnd_t rnd) 69{ 70 mpfr_t f; 71 mpz_t z; 72 mpfr_exp_t e; 73 int inex; 74 75 /* using CHAR_BIT * sizeof(long) bits of precision ensures that 76 mpfr_set_z_2exp is exact below */ 77 mpfr_init2 (f, CHAR_BIT * sizeof(long)); 78 mpz_init (z); 79 mpz_set_ui (z, i); 80 /* the following loop ensures that no overflow occurs */ 81 do 82 e = randexp (); 83 while (e > mpfr_get_emax () - CHAR_BIT * sizeof(long)); 84 inex = mpfr_set_z_2exp (f, z, e, rnd); 85 if (inex != 0) 86 { 87 printf ("Error in mpfr_set_z_2exp for i=%ld, e=%ld," 88 " wrong ternary value\n", i, (long) e); 89 printf ("expected 0, got %d\n", inex); 90 exit (1); 91 } 92 mpfr_div_2si (f, f, e, rnd); 93 if (mpfr_get_si (f, MPFR_RNDZ) != i) 94 { 95 printf ("Error in mpfr_set_z_2exp for i=%ld e=%ld rnd_mode=%d\n", 96 i, e, rnd); 97 printf ("expected %ld\n", i); 98 mpfr_printf ("got %Re\n", f); 99 exit (1); 100 } 101 mpfr_clear (f); 102 mpz_clear (z); 103} 104 105int 106main (int argc, char *argv[]) 107{ 108 long j; 109 110 tests_start_mpfr (); 111 112 check (0, MPFR_RNDN); 113 for (j = 0; j < 200000; j++) 114 check (randlimb () & LONG_MAX, RND_RAND ()); 115 check0 (); 116 117 tests_end_mpfr (); 118 119 return 0; 120} 121