/* Test file for mpfr_pow_z -- power function x^z with z a MPZ Copyright 2005 Free Software Foundation, Inc. This file is part of the MPFR Library. The MPFR Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The MPFR Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the MPFR Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "mpfr-test.h" #define ERROR(str) do { printf("Error for "str"\n"); exit (1); } while (0) static void check_special (void) { mpfr_t x, y; mpz_t z; int res; mpfr_init (x); mpfr_init (y); mpz_init (z); /* x^0 = 1 except for NAN */ mpfr_set_ui (x, 23, GMP_RNDN); mpz_set_ui (z, 0); res = mpfr_pow_z (y, x, z, GMP_RNDN); if (res != 0 || mpfr_cmp_ui (y, 1) != 0) ERROR ("23^0"); mpfr_set_nan (x); res = mpfr_pow_z (y, x, z, GMP_RNDN); if (res != 0 || mpfr_nan_p (y) == 0) ERROR ("NAN^0"); mpfr_set_inf (x, 1); res = mpfr_pow_z (y, x, z, GMP_RNDN); if (res != 0 || mpfr_cmp_ui (y, 1) != 0) ERROR ("INF^0"); /* sINF^N = INF if s==1 or n even if N > 0*/ mpz_set_ui (z, 42); mpfr_set_inf (x, 1); res = mpfr_pow_z (y, x, z, GMP_RNDN); if (res != 0 || mpfr_inf_p (y) == 0 || mpfr_sgn (y) <= 0) ERROR ("INF^42"); mpfr_set_inf (x, -1); res = mpfr_pow_z (y, x, z, GMP_RNDN); if (res != 0 || mpfr_inf_p (y) == 0 || mpfr_sgn (y) <= 0) ERROR ("-INF^42"); mpz_set_ui (z, 17); mpfr_set_inf (x, 1); res = mpfr_pow_z (y, x, z, GMP_RNDN); if (res != 0 || mpfr_inf_p (y) == 0 || mpfr_sgn (y) <= 0) ERROR ("INF^17"); mpfr_set_inf (x, -1); res = mpfr_pow_z (y, x, z, GMP_RNDN); if (res != 0 || mpfr_inf_p (y) == 0 || mpfr_sgn (y) >= 0) ERROR ("-INF^17"); mpz_set_si (z, -42); mpfr_set_inf (x, 1); res = mpfr_pow_z (y, x, z, GMP_RNDN); if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_SIGN (y) <= 0) ERROR ("INF^-42"); mpfr_set_inf (x, -1); res = mpfr_pow_z (y, x, z, GMP_RNDN); if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_SIGN (y) <= 0) ERROR ("-INF^-42"); mpz_set_si (z, -17); mpfr_set_inf (x, 1); res = mpfr_pow_z (y, x, z, GMP_RNDN); if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_SIGN (y) <= 0) ERROR ("INF^-17"); mpfr_set_inf (x, -1); res = mpfr_pow_z (y, x, z, GMP_RNDN); if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_SIGN (y) >= 0) ERROR ("-INF^-17"); /* s0^N = +0 if s==+ or n even if N > 0*/ mpz_set_ui (z, 42); MPFR_SET_ZERO (x); MPFR_SET_POS (x); res = mpfr_pow_z (y, x, z, GMP_RNDN); if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_SIGN (y) <= 0) ERROR ("+0^42"); MPFR_SET_NEG (x); res = mpfr_pow_z (y, x, z, GMP_RNDN); if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_SIGN (y) <= 0) ERROR ("-0^42"); mpz_set_ui (z, 17); MPFR_SET_POS (x); res = mpfr_pow_z (y, x, z, GMP_RNDN); if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_SIGN (y) <= 0) ERROR ("+0^17"); MPFR_SET_NEG (x); res = mpfr_pow_z (y, x, z, GMP_RNDN); if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_SIGN (y) >= 0) ERROR ("-0^17"); mpz_set_si (z, -42); MPFR_SET_ZERO (x); MPFR_SET_POS (x); res = mpfr_pow_z (y, x, z, GMP_RNDN); if (res != 0 || mpfr_inf_p (y) == 0 || MPFR_SIGN (y) <= 0) ERROR ("+0^-42"); MPFR_SET_NEG (x); res = mpfr_pow_z (y, x, z, GMP_RNDN); if (res != 0 || mpfr_inf_p (y) == 0 || MPFR_SIGN (y) <= 0) ERROR ("-0^-42"); mpz_set_si (z, -17); MPFR_SET_POS (x); res = mpfr_pow_z (y, x, z, GMP_RNDN); if (res != 0 || mpfr_inf_p (y) == 0 || MPFR_SIGN (y) <= 0) ERROR ("+0^-17"); MPFR_SET_NEG (x); res = mpfr_pow_z (y, x, z, GMP_RNDN); if (res != 0 || mpfr_inf_p (y) == 0 || MPFR_SIGN (y) >= 0) ERROR ("-0^-17"); mpz_clear (z); mpfr_clear (y); mpfr_clear (x); } static void check_integer (mp_prec_t begin, mp_prec_t end, unsigned long max) { mpfr_t x, y1, y2; mpz_t z; unsigned long i, n; mp_prec_t p; int res1, res2; mp_rnd_t rnd; mpfr_inits2 (begin, x, y1, y2, NULL); mpz_init (z); for (p = begin ; p < end ; p+=4) { mpfr_set_prec (x, p); mpfr_set_prec (y1, p); mpfr_set_prec (y2, p); for (i = 0 ; i < max ; i++) { mpz_random (z, (i&1) == 0 ? -1 : 1); mpfr_random (x); mpfr_mul_2ui (x, x, 1, GMP_RNDN); /* 0 <= x < 2 */ rnd = (mp_rnd_t) RND_RAND (); if (mpz_fits_slong_p (z)) { n = mpz_get_si (z); /* printf ("New test for x=%ld\nCheck Pow_si\n", n); */ res1 = mpfr_pow_si (y1, x, n, rnd); /* printf ("Check pow_z\n"); */ res2 = mpfr_pow_z (y2, x, z, rnd); if (mpfr_cmp (y1, y2) != 0) { printf ("Error for p=%lu, z=%ld, rnd=%s and x=", p, n, mpfr_print_rnd_mode (rnd)); mpfr_dump (x); printf ("Ypowui="); mpfr_dump (y1); printf ("Ypowz ="); mpfr_dump (y2); exit (1); } if (res1 != res2) { printf ("Wrong inexact flags for p=%lu, z=%ld, rnd=%s and x=", p, n, mpfr_print_rnd_mode (rnd)); mpfr_dump (x); printf ("Ypowui(%d)=", res1); mpfr_dump (y1); printf ("Ypowz (%d)=", res2); mpfr_dump (y2); exit (1); } } } /* for i */ } /* for p */ mpfr_clears (x, y1, y2, NULL); mpz_clear (z); } static void check_regression (void) { mpfr_t x, y; mpz_t z; int res1, res2; mpz_init_set_ui (z, 2026876995); mpfr_init2 (x, 122); mpfr_init2 (y, 122); mpfr_set_str_binary (x, "0.10000010010000111101001110100101101010011110011100001111000001001101000110011001001001001011001011010110110110101000111011E1"); res1 = mpfr_pow_z (y, x, z, GMP_RNDU); res2 = mpfr_pow_ui (x, x, 2026876995UL, GMP_RNDU); if (mpfr_cmp (x, y) || res1 != res2) { printf ("Regression (1) tested failed (%d=?%d)\n",res1, res2); printf ("pow_ui: "); mpfr_dump (x); printf ("pow_z: "); mpfr_dump (y); exit (1); } mpfr_clear (x); mpfr_clear (y); mpz_clear (z); } int main () { MPFR_TEST_USE_RANDS (); tests_start_mpfr (); check_special (); check_integer (2, 163, 100); check_regression (); tests_end_mpfr (); return 0; }