diff options
71 files changed, 6630 insertions, 620 deletions
diff --git a/mpfr/mpf2mpfr.h b/mpfr/mpf2mpfr.h index 7b7336a22..99b86204d 100644 --- a/mpfr/mpf2mpfr.h +++ b/mpfr/mpf2mpfr.h @@ -1,64 +1,138 @@ +/* mpf2mpfr.h -- Compatibility include file with mpf. + +Copyright (C) 1999, 2001 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. */ + /* types */ #define mpf_t mpfr_t /* functions which don't take as argument the rounding mode */ +#undef mpf_ceil #define mpf_ceil mpfr_ceil +#undef mpf_clear #define mpf_clear mpfr_clear +#undef mpf_cmp #define mpf_cmp mpfr_cmp +#undef mpf_cmp_si #define mpf_cmp_si mpfr_cmp_si +#undef mpf_cmp_ui #define mpf_cmp_ui mpfr_cmp_ui +#undef mpf_eq #define mpf_eq mpfr_eq +#undef mpf_floor #define mpf_floor mpfr_floor +#undef mpf_get_d #define mpf_get_d mpfr_get_d +#undef mpf_get_prec #define mpf_get_prec mpfr_get_prec +#undef mpf_init #define mpf_init mpfr_init +#undef mpf_init2 #define mpf_init2 mpfr_init2 +#undef mpf_random2 #define mpf_random2 mpfr_random2 +#undef mpf_set_default_prec #define mpf_set_default_prec mpfr_set_default_prec +#undef mpf_set_prec #define mpf_set_prec(x,p) mpfr_round(x,__gmp_default_rounding_mode,p) +#undef mpf_set_prec_raw #define mpf_set_prec_raw mpfr_set_prec_raw +#undef mpf_trunc #define mpf_trunc mpfr_trunc +#undef mpf_sgn #define mpf_sgn mpfr_sgn +#undef mpf_swap #define mpf_swap mpfr_swap /* functions which take as argument the rounding mode */ +#undef mpf_abs #define mpf_abs(x,y) mpfr_abs(x,y,__gmp_default_rounding_mode) -#define mpf_add(x,y,z) mpfr_add(x,y,z,__gmp_default_rounding_mode) +#undef mpf_add +#define mpf_add(x,y,z) mpfr_add(x,y,z,__gmp_default_rounding_mode) +#undef mpf_add_ui #define mpf_add_ui(x,y,z) \ mpfr_add_ui(x,y,z,__gmp_default_rounding_mode) -#define mpf_div(x,y,z) mpfr_div(x,y,z,__gmp_default_rounding_mode) +#undef mpf_div +#define mpf_div(x,y,z) mpfr_div(x,y,z,__gmp_default_rounding_mode) +#undef mpf_div_ui #define mpf_div_ui(x,y,z) \ - mpfr_div_ui(x,y,z,__gmp_default_rounding_mode) + mpfr_div_ui(x,y,z,__gmp_default_rounding_mode) +#undef mpf_div_2exp #define mpf_div_2exp(x,y,z) \ - mpfr_div_2exp(x,y,z,__gmp_default_rounding_mode) + mpfr_div_2exp(x,y,z,__gmp_default_rounding_mode) +#undef mpf_dump #define mpf_dump(x,y,z) \ mpfr_dump(x,y,z,__gmp_default_rounding_mode) +#undef mpf_get_str #define mpf_get_str(x,y,z,t,u) \ - mpfr_get_str(x,y,z,t,u,__gmp_default_rounding_mode) + mpfr_get_str(x,y,z,t,u,__gmp_default_rounding_mode) +#undef mpf_inp_str #define mpf_inp_str(x,y,z) mpfr_inp_str(x,y,z,__gmp_default_rounding_mode) +#undef mpf_set_str #define mpf_set_str(x,y,z) mpfr_set_str(x,y,z,__gmp_default_rounding_mode) -#define mpf_init_set(x,y) mpfr_init_set(x,y,__gmp_default_rounding_mode) -#define mpf_init_set_d(x,y) mpfr_init_set_d(x,y,__gmp_default_rounding_mode) -#define mpf_init_set_si(x,y) mpfr_init_set_si(x,y,__gmp_default_rounding_mode) -#define mpf_init_set_str(x,y,z) mpfr_init_set_str(x,y,z,__gmp_default_rounding_mode) -#define mpf_init_set_ui(x,y) mpfr_init_set_ui(x,y,__gmp_default_rounding_mode) -#define mpf_mul(x,y,z) mpfr_mul(x,y,z,__gmp_default_rounding_mode) -#define mpf_mul_2exp(x,y,z) mpfr_mul_2exp(x,y,z,__gmp_default_rounding_mode) -#define mpf_mul_ui(x,y,z) mpfr_mul_ui(x,y,z,__gmp_default_rounding_mode) -#define mpf_neg(x,y) mpfr_neg(x,y,__gmp_default_rounding_mode) -#define mpf_out_str(x,y,z,t) mpfr_out_str(x,y,z,t,__gmp_default_rounding_mode) -#define mpf_pow_ui(x,y,z) mpfr_pow_ui(x,y,z,__gmp_default_rounding_mode) +#undef mpf_init_set +#define mpf_init_set(x,y) mpfr_init_set(x,y,__gmp_default_rounding_mode) +#undef mpf_init_set_d +#define mpf_init_set_d(x,y) mpfr_init_set_d(x,y,__gmp_default_rounding_mode) +#undef mpf_init_set_si +#define mpf_init_set_si(x,y) mpfr_init_set_si(x,y,__gmp_default_rounding_mode) +#undef mpf_init_set_str +#define mpf_init_set_str(x,y,z) mpfr_init_set_str(x,y,z,__gmp_default_rounding_mode) +#undef mpf_init_set_ui +#define mpf_init_set_ui(x,y) mpfr_init_set_ui(x,y,__gmp_default_rounding_mode) +#undef mpf_mul +#define mpf_mul(x,y,z) mpfr_mul(x,y,z,__gmp_default_rounding_mode) +#undef mpf_mul_2exp +#define mpf_mul_2exp(x,y,z) mpfr_mul_2exp(x,y,z,__gmp_default_rounding_mode) +#undef mpf_mul_ui +#define mpf_mul_ui(x,y,z) mpfr_mul_ui(x,y,z,__gmp_default_rounding_mode) +#undef mpf_neg +#define mpf_neg(x,y) mpfr_neg(x,y,__gmp_default_rounding_mode) +#undef mpf_out_str +#define mpf_out_str(x,y,z,t) mpfr_out_str(x,y,z,t,__gmp_default_rounding_mode) +#undef mpf_pow_ui +#define mpf_pow_ui(x,y,z) mpfr_pow_ui(x,y,z,__gmp_default_rounding_mode) +#undef mpf_reldiff #define mpf_reldiff(x,y,z) mpfr_reldiff(x,y,z,__gmp_default_rounding_mode) -#define mpf_set(x,y) mpfr_set(x,y,__gmp_default_rounding_mode) -#define mpf_set_d(x,y) mpfr_set_d(x,y,__gmp_default_rounding_mode) -#define mpf_set_q(x,y) mpfr_set_q(x,y,__gmp_default_rounding_mode) -#define mpf_set_si(x,y) mpfr_set_si(x,y,__gmp_default_rounding_mode) -#define mpf_set_ui(x,y) mpfr_set_ui(x,y,__gmp_default_rounding_mode) -#define mpf_set_z(x,y) mpfr_set_z(x,y,__gmp_default_rounding_mode) -#define mpf_sqrt(x,y) mpfr_sqrt(x,y,__gmp_default_rounding_mode) +#undef mpf_set +#define mpf_set(x,y) mpfr_set(x,y,__gmp_default_rounding_mode) +#undef mpf_set_d +#define mpf_set_d(x,y) mpfr_set_d(x,y,__gmp_default_rounding_mode) +#undef mpf_set_q +#define mpf_set_q(x,y) mpfr_set_q(x,y,__gmp_default_rounding_mode) +#undef mpf_set_si +#define mpf_set_si(x,y) mpfr_set_si(x,y,__gmp_default_rounding_mode) +#undef mpf_set_ui +#define mpf_set_ui(x,y) mpfr_set_ui(x,y,__gmp_default_rounding_mode) +#undef mpf_set_z +#define mpf_set_z(x,y) mpfr_set_z(x,y,__gmp_default_rounding_mode) +#undef mpf_sqrt +#define mpf_sqrt(x,y) mpfr_sqrt(x,y,__gmp_default_rounding_mode) +#undef mpf_sqrt_ui #define mpf_sqrt_ui(x,y) mpfr_sqrt_ui(x,y,__gmp_default_rounding_mode) -#define mpf_sub(x,y,z) mpfr_sub(x,y,z,__gmp_default_rounding_mode) -#define mpf_sub_ui(x,y,z) mpfr_sub_ui(x,y,z,__gmp_default_rounding_mode) +#undef mpf_sub +#define mpf_sub(x,y,z) mpfr_sub(x,y,z,__gmp_default_rounding_mode) +#undef mpf_sub_ui +#define mpf_sub_ui(x,y,z) mpfr_sub_ui(x,y,z,__gmp_default_rounding_mode) +#undef mpf_ui_div #define mpf_ui_div(x,y,z) mpfr_ui_div(x,y,z,__gmp_default_rounding_mode) +#undef mpf_ui_sub #define mpf_ui_sub(x,y,z) mpfr_ui_sub(x,y,z,__gmp_default_rounding_mode) +#undef mpf_urandomb #define mpf_urandomb(x,y,n) mpfr_urandomb(x,y) diff --git a/mpfr/mpfr-impl.h b/mpfr/mpfr-impl.h index 3e904d999..fc18e4a01 100644 --- a/mpfr/mpfr-impl.h +++ b/mpfr/mpfr-impl.h @@ -1,27 +1,53 @@ /* Utilities for MPFR developers, not exported. -Copyright (C) 1999-2000 Free Software Foundation. +Copyright (C) 1999, 2000, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ +/* This unsigned type must correspond to the signed one defined in gmp.h */ +#if defined (_CRAY) && ! defined (_CRAYMPP) +typedef unsigned int mp_exp_unsigned_t; +typedef unsigned int mp_size_unsigned_t; +#else +typedef unsigned long int mp_exp_unsigned_t; +typedef unsigned long int mp_size_unsigned_t; +#endif + +#define MP_LIMB_T_ONE ((mp_limb_t) 1) + +/* Assertions */ + +/* Compile with -DWANT_ASSERT to check all assert statements */ + +/* MPFR_ASSERTN(expr): assertion checked in the normal debug level */ +#define MPFR_ASSERTN(expr) ASSERT_ALWAYS(expr) + +/* MPFR_ASSERTD(expr): assertion checked in debug level 33 or higher */ +#define MPFR_ASSERTD(expr) ASSERT(expr) + /* Definition of constants */ #define LOG2 0.69314718055994528622 /* log(2) rounded to zero on 53 bits */ +#define ALPHA 4.3191365662914471407 /* a+2 = a*log(a), rounded to +infinity */ + +/* Safe absolute value (to avoid possible integer overflow) */ + +#define SAFE_ABS(type,x) ((x) >= 0 ? (unsigned type)(x) : -(unsigned type)(x)) /* macros for doubles, based on gmp union ieee_double_extract */ @@ -39,35 +65,55 @@ typedef union ieee_double_extract Ieee_double_extract; bit 30 of _mpfr_size is used for Nan flag, bit 29 of _mpfr_size is used for Inf flag, remaining bits are used to store the number of allocated limbs */ -#define MPFR_CLEAR_FLAGS(x) (((x) -> _mpfr_size &= ~(3 << 29))) -#define MPFR_IS_NAN(x) (((x)->_mpfr_size >> 30)&1) -#define MPFR_SET_NAN(x) ((x)->_mpfr_size |= (1<<30)) -#define MPFR_CLEAR_NAN(x) (((x) -> _mpfr_size &= ~(1 << 30))) -#define MPFR_IS_INF(x) (((x)->_mpfr_size >> 29)&1) -#define MPFR_SET_INF(x) ((x)->_mpfr_size |= (1<<29)) -#define MPFR_CLEAR_INF(x) ((x)->_mpfr_size &= ~(1 << 29)) +#define MPFR_CLEAR_FLAGS(x) \ + (((x) -> _mpfr_size &= ~((mp_size_unsigned_t) 3 << 29))) +#define MPFR_IS_NAN(x) (((x)->_mpfr_size >> 30) & 1) +#define MPFR_SET_NAN(x) ((x)->_mpfr_size |= ((mp_size_unsigned_t) 1 << 30)) +#define MPFR_CLEAR_NAN(x) \ + (((x) -> _mpfr_size &= ~((mp_size_unsigned_t) 1 << 30))) +#define MPFR_IS_INF(x) (((x)->_mpfr_size >> 29) & 1) +#define MPFR_SET_INF(x) ((x)->_mpfr_size |= ((mp_size_unsigned_t) 1 << 29)) +#define MPFR_CLEAR_INF(x) ((x)->_mpfr_size &= ~((mp_size_unsigned_t) 1 << 29)) #define MPFR_IS_FP(x) ((((x) -> _mpfr_size >> 29) & 3) == 0) -#define MPFR_ABSSIZE(x) ((x)->_mpfr_size & ((1<<29)-1)) +#define MPFR_ABSSIZE(x) \ + ((x)->_mpfr_size & (((mp_size_unsigned_t) 1 << 29) - 1)) #define MPFR_SIZE(x) ((x)->_mpfr_size) #define MPFR_EXP(x) ((x)->_mpfr_exp) #define MPFR_MANT(x) ((x)->_mpfr_d) -#define MPFR_ISNONNEG(x) (MPFR_NOTZERO((x)) && MPFR_SIGN(x)>=0) -#define MPFR_ISNEG(x) (MPFR_NOTZERO((x)) && MPFR_SIGN(x)==-1) -#define MPFR_CHANGE_SIGN(x) (MPFR_SIZE(x) ^= (((mp_size_t)1)<<31)) -#define MPFR_SET_SAME_SIGN(x, y) if (MPFR_SIGN((x)) != MPFR_SIGN((y))) { MPFR_CHANGE_SIGN((x)); } +#define MPFR_ISNONNEG(x) (MPFR_NOTZERO((x)) && MPFR_SIGN(x) >= 0) +#define MPFR_ISNEG(x) (MPFR_NOTZERO((x)) && MPFR_SIGN(x) == -1) +#define MPFR_SET_POS(x) (MPFR_SIZE(x) &= ~(((mp_size_unsigned_t) 1) << 31)) +#define MPFR_SET_NEG(x) (MPFR_SIZE(x) |= (((mp_size_unsigned_t) 1) << 31)) +#define MPFR_CHANGE_SIGN(x) (MPFR_SIZE(x) ^= (((mp_size_unsigned_t) 1) << 31)) +#define MPFR_SET_SAME_SIGN(x, y) \ + (MPFR_SIGN((x)) != MPFR_SIGN((y)) && (MPFR_CHANGE_SIGN((x)), 0)) #define MPFR_PREC(x) ((x)->_mpfr_prec) -#define MPFR_NOTZERO(x) (MPFR_MANT(x)[(MPFR_PREC(x)-1)/BITS_PER_MP_LIMB]) -#define MPFR_IS_ZERO(x) ((MPFR_NOTZERO(x))==0) -#define MPFR_SET_ZERO(x) (MPFR_MANT(x)[(MPFR_PREC(x)-1)/BITS_PER_MP_LIMB] = 0) +#define MPFR_NOTZERO(x) \ + (MPFR_MANT(x)[(MPFR_PREC(x)-1)/BITS_PER_MP_LIMB] != (mp_limb_t) 0) +#define MPFR_IS_ZERO(x) \ + (MPFR_MANT(x)[(MPFR_PREC(x)-1)/BITS_PER_MP_LIMB] == (mp_limb_t) 0) +#define MPFR_SET_ZERO(x) \ + (MPFR_MANT(x)[(MPFR_PREC(x)-1)/BITS_PER_MP_LIMB] = (mp_limb_t) 0) +#define MPFR_ESIZE(x) \ + ((MPFR_PREC((x)) - 1) / BITS_PER_MP_LIMB + 1); +#define MPFR_EVEN_INEX 2 + +/* When returning the ternary inexact value, ALWAYS use one of the + following two macros, unless the flag comes from another function + returning the ternary inexact value */ +#define MPFR_RET(I) return \ + (I) ? ((__mpfr_flags |= MPFR_FLAGS_INEXACT), (I)) : 0 +#define MPFR_RET_NAN return (__mpfr_flags |= MPFR_FLAGS_NAN), 0 /* Memory gestion */ /* temporary allocate s limbs at xp, and initialize mpfr variable x */ -#define MPFR_INIT(xp, x, p, s) xp = (mp_ptr) TMP_ALLOC(s*BYTES_PER_MP_LIMB); \ - MPFR_PREC(x) = p; MPFR_MANT(x) = xp; MPFR_SIZE(x) = s; MPFR_EXP(x) = 0; +#define MPFR_INIT(xp, x, p, s) \ + (xp = (mp_ptr) TMP_ALLOC((s)*BYTES_PER_MP_LIMB), \ + MPFR_PREC(x) = p, MPFR_MANT(x) = xp, MPFR_SIZE(x) = s, MPFR_EXP(x) = 0) /* same when xp is already allocated */ #define MPFR_INIT1(xp, x, p, s) \ - MPFR_PREC(x)=p; MPFR_MANT(x)=xp; MPFR_SIZE(x)=s; + (MPFR_PREC(x) = p, MPFR_MANT(x) = xp, MPFR_SIZE(x) = s) #ifndef _PROTO #if defined (__STDC__) || defined (__cplusplus) @@ -81,20 +127,35 @@ typedef union ieee_double_extract Ieee_double_extract; extern "C" { #endif -int mpfr_round_raw _PROTO ((mp_limb_t *, mp_limb_t *, mp_prec_t, int, - mp_prec_t, mp_rnd_t)); -int mpfr_round_raw2 _PROTO((mp_limb_t *, mp_prec_t, int, mp_rnd_t, mp_prec_t)); +int mpfr_set_underflow _PROTO ((mpfr_ptr, mp_rnd_t, int)); +int mpfr_set_overflow _PROTO ((mpfr_ptr, mp_rnd_t, int)); +void mpfr_save_emin_emax _PROTO ((void)); +void mpfr_restore_emin_emax _PROTO ((void)); +int mpfr_add1 _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, + mp_rnd_t, mp_exp_unsigned_t)); +int mpfr_sub1 _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, + mp_rnd_t, mp_exp_unsigned_t)); +int mpfr_round_raw_generic _PROTO ((mp_limb_t *, mp_limb_t *, mp_prec_t, int, + mp_prec_t, mp_rnd_t, int *, int)); int mpfr_can_round_raw _PROTO ((mp_limb_t *, mp_prec_t, int, mp_prec_t, mp_rnd_t, mp_rnd_t, mp_prec_t)); double mpfr_get_d2 _PROTO ((mpfr_srcptr, long)); mp_size_t mpn_sqrtrem_new _PROTO ((mp_limb_t *, mp_limb_t *, mp_limb_t *, mp_size_t)); -int mpfr_cmp2 _PROTO ((mpfr_srcptr, mpfr_srcptr)); +int mpfr_cmp_abs _PROTO ((mpfr_srcptr, mpfr_srcptr)); +mp_prec_t mpfr_cmp2 _PROTO ((mpfr_srcptr, mpfr_srcptr)); long _mpfr_ceil_log2 _PROTO ((double)); long _mpfr_floor_log2 _PROTO ((double)); double _mpfr_ceil_exp2 _PROTO ((double)); unsigned long _mpfr_isqrt _PROTO ((unsigned long)); unsigned long _mpfr_cuberoot _PROTO ((unsigned long)); +#define mpfr_round_raw(yp, xp, xprec, neg, yprec, r, inexp) \ + mpfr_round_raw_generic((yp), (xp), (xprec), (neg), (yprec), (r), (inexp), 0) + +#define mpfr_round_raw2(xp, xn, neg, r, prec) \ + mpfr_round_raw_generic(NULL, (xp), (xn) * BITS_PER_MP_LIMB, (neg), \ + (prec), (r), 0, 1); + #if defined (__cplusplus) } #endif diff --git a/mpfr/mpfr-test.h b/mpfr/mpfr-test.h index 8db884ca9..bc49a7af5 100644 --- a/mpfr/mpfr-test.h +++ b/mpfr/mpfr-test.h @@ -1,20 +1,20 @@ /* auxiliary functions for MPFR tests. -Copyright (C) 1999-2000 Free Software Foundation. +Copyright (C) 1999, 2000, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ diff --git a/mpfr/mpfr.h b/mpfr/mpfr.h index 4f377248e..e22e60ac8 100644 --- a/mpfr/mpfr.h +++ b/mpfr/mpfr.h @@ -1,27 +1,33 @@ /* mpfr.h -- Include file for mpfr. -Copyright (C) 1999 Free Software Foundation. +Copyright (C) 1999, 2000, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ #ifndef __MPFR_H #define __MPFR_H -#include <stdio.h> + +/* check if stdio.h is included */ +#if defined (FILE) || defined (H_STDIO) || defined (_H_STDIO) \ + || defined (_STDIO_H) || defined (_STDIO_H_) || defined (__STDIO_H__) \ + || defined (_STDIO_INCLUDED) || defined (__dj_include_stdio_h_) +#define _MPFR_H_HAVE_FILE 1 +#endif /* Definition of rounding modes */ @@ -30,6 +36,24 @@ MA 02111-1307, USA. */ #define GMP_RNDU 2 #define GMP_RNDD 3 +/* Definition of exponent limits */ + +#define MPFR_EMAX_DEFAULT ((mp_exp_t) ((1UL<<31)-1)) +#define MPFR_EMIN_DEFAULT (-(MPFR_EMAX_DEFAULT)) + +#define MPFR_EMIN_MIN MPFR_EMIN_DEFAULT +#define MPFR_EMIN_MAX MPFR_EMAX_DEFAULT +#define MPFR_EMAX_MIN MPFR_EMIN_DEFAULT +#define MPFR_EMAX_MAX MPFR_EMAX_DEFAULT + +/* Flags */ + +#define MPFR_FLAGS_UNDERFLOW 1 +#define MPFR_FLAGS_OVERFLOW 2 +#define MPFR_FLAGS_NAN 4 +#define MPFR_FLAGS_INEXACT 8 +#define MPFR_FLAGS_ALL 15 + /* Definitions of types and their semantics */ typedef unsigned long int mp_prec_t; /* easy to change if necessary */ @@ -85,19 +109,37 @@ typedef __gmp_const __mpfr_struct *mpfr_srcptr; extern "C" { #endif +extern unsigned int __mpfr_flags; +extern mp_exp_t __mpfr_emin; +extern mp_exp_t __mpfr_emax; +mp_exp_t mpfr_get_emin _PROTO ((void)); +int mpfr_set_emin _PROTO ((mp_exp_t)); +mp_exp_t mpfr_get_emax _PROTO ((void)); +int mpfr_set_emax _PROTO ((mp_exp_t)); +void mpfr_clear_flags _PROTO ((void)); +void mpfr_clear_underflow _PROTO ((void)); +void mpfr_clear_overflow _PROTO ((void)); +void mpfr_clear_nanflag _PROTO ((void)); +void mpfr_clear_inexflag _PROTO ((void)); +int mpfr_check_range _PROTO ((mpfr_ptr, mp_rnd_t)); +int mpfr_underflow_p _PROTO ((void)); +int mpfr_overflow_p _PROTO ((void)); +int mpfr_nanflag_p _PROTO ((void)); +int mpfr_inexflag_p _PROTO ((void)); + void mpfr_init2 _PROTO ((mpfr_ptr, mp_prec_t)); void mpfr_init _PROTO ((mpfr_ptr)); -void mpfr_round _PROTO ((mpfr_ptr, mp_rnd_t, mp_prec_t)); +int mpfr_round _PROTO ((mpfr_ptr, mp_rnd_t, mp_prec_t)); int mpfr_can_round _PROTO ((mpfr_ptr, mp_prec_t, mp_rnd_t, mp_rnd_t, mp_prec_t)); -void mpfr_set_d _PROTO ((mpfr_ptr, double, mp_rnd_t)); +int mpfr_set_d _PROTO ((mpfr_ptr, double, mp_rnd_t)); int mpfr_set_z _PROTO ((mpfr_ptr, mpz_srcptr, mp_rnd_t)); mp_exp_t mpz_set_fr _PROTO ((mpz_ptr, mpfr_srcptr)); -void mpfr_set_q _PROTO ((mpfr_ptr, mpq_srcptr, mp_rnd_t)); +int mpfr_set_q _PROTO ((mpfr_ptr, mpq_srcptr, mp_rnd_t)); double mpfr_get_d _PROTO ((mpfr_srcptr)); -void mpfr_set_f _PROTO ((mpfr_ptr, mpf_srcptr, mp_rnd_t)); -void mpfr_set_si _PROTO ((mpfr_ptr, long, mp_rnd_t)); -void mpfr_set_ui _PROTO ((mpfr_ptr, unsigned long, mp_rnd_t)); +int mpfr_set_f _PROTO ((mpfr_ptr, mpf_srcptr, mp_rnd_t)); +int mpfr_set_si _PROTO ((mpfr_ptr, long, mp_rnd_t)); +int mpfr_set_ui _PROTO ((mpfr_ptr, unsigned long, mp_rnd_t)); void mpfr_print_raw _PROTO ((mpfr_srcptr)); void mpfr_random _PROTO ((mpfr_ptr)); void mpfr_random2 _PROTO ((mpfr_ptr, mp_size_t, mp_exp_t)); @@ -106,46 +148,52 @@ void mpfr_clear _PROTO ((mpfr_ptr)); void mpfr_set_str_raw _PROTO ((mpfr_ptr, char *)); int mpfr_set_str _PROTO ((mpfr_ptr, __gmp_const char *, int, mp_rnd_t)); int mpfr_init_set_str _PROTO ((mpfr_ptr, char *, int, mp_rnd_t)); -size_t mpfr_inp_str _PROTO ((mpfr_ptr, FILE *, int, mp_rnd_t)); char* mpfr_get_str _PROTO ((char *, mp_exp_t *, int, size_t, mpfr_srcptr, mp_rnd_t)); +#ifdef _MPFR_H_HAVE_FILE +size_t mpfr_inp_str _PROTO ((mpfr_ptr, FILE *, int, mp_rnd_t)); size_t mpfr_out_str _PROTO ((FILE *, int, size_t, mpfr_srcptr, mp_rnd_t)); -void mpfr_mul _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); +#endif +int mpfr_mul _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); int mpfr_pow_ui _PROTO ((mpfr_ptr, mpfr_srcptr, unsigned long int, mp_rnd_t)); int mpfr_ui_pow_ui _PROTO ((mpfr_ptr, unsigned long int, unsigned long int, mp_rnd_t)); -void mpfr_div _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_div _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); void mpfr_agm _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); int mpfr_sqrt _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); int mpfr_sqrt_ui _PROTO ((mpfr_ptr, unsigned long, mp_rnd_t)); -void mpfr_add _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); -void mpfr_add_ui _PROTO ((mpfr_ptr, mpfr_srcptr, unsigned long, mp_rnd_t)); -void mpfr_sub_ui _PROTO ((mpfr_ptr, mpfr_srcptr, unsigned long, mp_rnd_t)); +int mpfr_add _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_add_ui _PROTO ((mpfr_ptr, mpfr_srcptr, unsigned long, mp_rnd_t)); +int mpfr_sub_ui _PROTO ((mpfr_ptr, mpfr_srcptr, unsigned long, mp_rnd_t)); void mpfr_add_one_ulp _PROTO ((mpfr_ptr)); -void mpfr_sub _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); -void mpfr_ui_sub _PROTO ((mpfr_ptr, unsigned long, mpfr_srcptr, mp_rnd_t)); +int mpfr_sub _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_ui_sub _PROTO ((mpfr_ptr, unsigned long, mpfr_srcptr, mp_rnd_t)); void mpfr_reldiff _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); void mpfr_const_pi _PROTO ((mpfr_ptr, mp_rnd_t)); void mpfr_const_log2 _PROTO ((mpfr_ptr, mp_rnd_t)); +int mpfr_const_euler _PROTO ((mpfr_ptr, mp_rnd_t)); int mpfr_log _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); int mpfr_exp _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); -int mpfr_sin_cos _PROTO ((mpfr_ptr, mpfr_ptr, mpfr_srcptr, mp_rnd_t)); -void mpfr_mul_ui _PROTO((mpfr_ptr, mpfr_srcptr, unsigned long int, mp_rnd_t)); +int mpfr_exp2 _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_sin _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_cos _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_tan _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_mul_ui _PROTO((mpfr_ptr, mpfr_srcptr, unsigned long int, mp_rnd_t)); void mpfr_set_machine_rnd_mode _PROTO ((mp_rnd_t)); int mpfr_cmp_ui_2exp _PROTO ((mpfr_srcptr, unsigned long int, int)); int mpfr_cmp_si_2exp _PROTO ((mpfr_srcptr, long int, int)); -void mpfr_mul_2exp _PROTO((mpfr_ptr, mpfr_srcptr, unsigned long int,mp_rnd_t)); -void mpfr_div_2exp _PROTO((mpfr_ptr, mpfr_srcptr, unsigned long int,mp_rnd_t)); -void mpfr_set_prec _PROTO((mpfr_ptr, mp_prec_t)); +int mpfr_mul_2exp _PROTO((mpfr_ptr, mpfr_srcptr, unsigned long int, mp_rnd_t)); +int mpfr_div_2exp _PROTO((mpfr_ptr, mpfr_srcptr, unsigned long int, mp_rnd_t)); +int mpfr_set_prec _PROTO((mpfr_ptr, mp_prec_t)); void mpfr_set_prec_raw _PROTO((mpfr_ptr, mp_prec_t)); void mpfr_set_default_prec _PROTO((mp_prec_t)); mp_prec_t mpfr_get_default_prec _PROTO((void)); extern mp_prec_t __mpfr_default_fp_bit_precision; extern mp_rnd_t __gmp_default_rounding_mode; char * mpfr_print_rnd_mode _PROTO((mp_rnd_t)); -void mpfr_neg _PROTO((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_neg _PROTO((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); void mpfr_sub_one_ulp _PROTO((mpfr_ptr)); int mpfr_div_ui _PROTO((mpfr_ptr, mpfr_srcptr, unsigned long int, mp_rnd_t)); -void mpfr_ui_div _PROTO((mpfr_ptr, unsigned long int, mpfr_srcptr, mp_rnd_t)); +int mpfr_ui_div _PROTO((mpfr_ptr, unsigned long int, mpfr_srcptr, mp_rnd_t)); mp_prec_t mpfr_get_prec _PROTO((mpfr_srcptr)); void mpfr_set_default_rounding_mode _PROTO((mp_rnd_t)); int mpfr_eq _PROTO((mpfr_srcptr, mpfr_srcptr, unsigned long)); @@ -155,16 +203,82 @@ void mpfr_ceil _PROTO((mpfr_ptr, mpfr_srcptr)); void mpfr_extract _PROTO((mpz_ptr, mpfr_srcptr, unsigned int)); void mpfr_swap _PROTO((mpfr_ptr, mpfr_ptr)); void mpfr_dump _PROTO((mpfr_srcptr, mp_rnd_t)); -void mpfr_set4 _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t, int)); -int mpfr_cmp3 _PROTO ((mpfr_srcptr, mpfr_srcptr, long int)); +int mpfr_set4 _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t, int)); +int mpfr_cmp3 _PROTO ((mpfr_srcptr, mpfr_srcptr, int)); int mpfr_nan_p _PROTO((mpfr_srcptr)); int mpfr_inf_p _PROTO((mpfr_srcptr)); int mpfr_number_p _PROTO((mpfr_srcptr)); +int mpfr_asin _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_atan _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); + +int mpfr_sinh _PROTO((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_tanh _PROTO((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_factorial _PROTO ((mpfr_ptr, unsigned long int, mp_rnd_t)); +int mpfr_ui_pow _PROTO ((mpfr_ptr, unsigned long int, mpfr_srcptr, mp_rnd_t)); + +int mpfr_atanh _PROTO((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_acosh _PROTO((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_asinh _PROTO((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); + +int mpfr_cosh _PROTO((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_sinh _PROTO((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_tanh _PROTO((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_asin _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_atan _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_fac_ui _PROTO ((mpfr_ptr, unsigned long int, mp_rnd_t)); +int mpfr_fma _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_hypot _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_pow _PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_srcptr, mp_rnd_t)); +int mpfr_pow_si _PROTO ((mpfr_ptr, mpfr_srcptr, long int, mp_rnd_t)); +int mpfr_isinteger _PROTO ((mpfr_srcptr)); +int mpfr_log2 _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_log10 _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_log1p _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_expm1 _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_cbrt _PROTO ((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); + +int mpfr_min _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_max _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_dim _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); +int mpfr_copysign _PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t)); + +int mpfr_mul_z _PROTO ((mpfr_ptr, mpfr_srcptr, mpz_srcptr, mp_rnd_t)); +int mpfr_div_z _PROTO ((mpfr_ptr, mpfr_srcptr, mpz_srcptr, mp_rnd_t)); +int mpfr_add_z _PROTO ((mpfr_ptr, mpfr_srcptr, mpz_srcptr, mp_rnd_t)); +int mpfr_sub_z _PROTO ((mpfr_ptr, mpfr_srcptr, mpz_srcptr, mp_rnd_t)); + +int mpfr_mul_q _PROTO ((mpfr_ptr, mpfr_srcptr, mpq_srcptr, mp_rnd_t)); +int mpfr_div_q _PROTO ((mpfr_ptr, mpfr_srcptr, mpq_srcptr, mp_rnd_t)); +int mpfr_add_q _PROTO ((mpfr_ptr, mpfr_srcptr, mpq_srcptr, mp_rnd_t)); +int mpfr_sub_q _PROTO ((mpfr_ptr, mpfr_srcptr, mpq_srcptr, mp_rnd_t)); #if defined (__cplusplus) } #endif +/* prevent from using mpfr_get_e{min,max} as lvalues */ +#define mpfr_get_emin() (__mpfr_emin + 0) +#define mpfr_get_emax() (__mpfr_emax + 0) + +#define mpfr_clear_flags() \ + ((void) (__mpfr_flags = 0)) +#define mpfr_clear_underflow() \ + ((void) (__mpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_UNDERFLOW)) +#define mpfr_clear_overflow() \ + ((void) (__mpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_OVERFLOW)) +#define mpfr_clear_nanflag() \ + ((void) (__mpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_NAN)) +#define mpfr_clear_inexflag() \ + ((void) (__mpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_INEXACT)) +#define mpfr_underflow_p() \ + ((int) (__mpfr_flags & MPFR_FLAGS_UNDERFLOW)) +#define mpfr_overflow_p() \ + ((int) (__mpfr_flags & MPFR_FLAGS_OVERFLOW)) +#define mpfr_nanflag_p() \ + ((int) (__mpfr_flags & MPFR_FLAGS_NAN)) +#define mpfr_inexflag_p() \ + ((int) (__mpfr_flags & MPFR_FLAGS_INEXACT)) + #define mpfr_cmp_ui(b,i) mpfr_cmp_ui_2exp((b),(i),0) #define mpfr_cmp_si(b,i) mpfr_cmp_si_2exp((b),(i),0) #define mpfr_set(a,b,r) mpfr_set4(a,b,r,MPFR_SIGN(b)) @@ -173,14 +287,18 @@ int mpfr_number_p _PROTO((mpfr_srcptr)); #define mpfr_sgn(x) mpfr_cmp_ui(x,0) #define mpfr_init_set_si(x, i, rnd) \ - do { mpfr_init(x); mpfr_set_si((x), (i), (rnd)); } while (0) + ( mpfr_init(x), mpfr_set_si((x), (i), (rnd)) ) #define mpfr_init_set_ui(x, i, rnd) \ - do { mpfr_init(x); mpfr_set_ui((x), (i), (rnd)); } while (0) + ( mpfr_init(x), mpfr_set_ui((x), (i), (rnd)) ) #define mpfr_init_set_d(x, d, rnd) \ - do { mpfr_init(x); mpfr_set_d((x), (d), (rnd)); } while (0) + ( mpfr_init(x), mpfr_set_d((x), (d), (rnd)) ) +#define mpfr_init_set_z(x, i, rnd) \ + ( mpfr_init(x), mpfr_set_z((x), (i), (rnd)) ) +#define mpfr_init_set_q(x, i, rnd) \ + ( mpfr_init(x), mpfr_set_q((x), (i), (rnd)) ) #define mpfr_init_set(x, y, rnd) \ - do { mpfr_init(x); mpfr_set((x), (y), (rnd)); } while (0) + ( mpfr_init(x), mpfr_set((x), (y), (rnd)) ) #define mpfr_init_set_f(x, y, rnd) \ - do { mpfr_init(x); mpfr_set_f((x), (y), (rnd)); } while (0) + ( mpfr_init(x), mpfr_set_f((x), (y), (rnd)) ) #endif diff --git a/mpfr/tests/reuse.c b/mpfr/tests/reuse.c index d8214acb8..ca32b810d 100644 --- a/mpfr/tests/reuse.c +++ b/mpfr/tests/reuse.c @@ -1,30 +1,33 @@ /* Test file for in-place operations. -Copyright (C) 2000 Free Software Foundation. +Copyright (C) 2000, 2001 Free Software Foundation. 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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 <stdio.h> +#include <stdlib.h> #include "gmp.h" #include "mpfr.h" #include "mpfr-impl.h" void (*testfunc) () = NULL; void test3 (char *, mp_prec_t, mp_rnd_t); +void test4 (char *, mp_prec_t, mp_rnd_t); void test3a (char *, mp_prec_t, mp_rnd_t); void test2ui (char *, mp_prec_t, mp_rnd_t); void testui2 (char *, mp_prec_t, mp_rnd_t); @@ -35,7 +38,8 @@ int mpfr_compare (mpfr_t, mpfr_t); /* same than mpfr_cmp, but returns 0 for both NaN's */ int mpfr_compare (mpfr_t a, mpfr_t b) { - return (MPFR_IS_NAN(a)) ? !MPFR_IS_NAN(b) : mpfr_cmp(a, b); + return (MPFR_IS_NAN(a)) ? !MPFR_IS_NAN(b) : + (MPFR_IS_NAN(b) || mpfr_cmp(a, b)); } void test3 (char *foo, mp_prec_t prec, mp_rnd_t rnd) @@ -71,10 +75,11 @@ void test3 (char *foo, mp_prec_t prec, mp_rnd_t rnd) /* reference call: foo(a, b, c) */ testfunc (ref1, ref2, ref3, rnd); - + /* foo(a, a, c) */ mpfr_set (res1, ref2, rnd); /* exact operation */ testfunc (res1, res1, ref3, rnd); + if (mpfr_compare (res1, ref1)) { fprintf (stderr, "Error for %s(a, a, c) for a=%e, c=%e\n", foo, mpfr_get_d (ref2), mpfr_get_d (ref3)); @@ -99,7 +104,8 @@ void test3 (char *foo, mp_prec_t prec, mp_rnd_t rnd) testfunc (ref1, ref2, ref3, rnd); mpfr_set (res1, ref2, rnd); testfunc (res1, res1, res1, rnd); - if (mpfr_compare (res1, ref1)) { + + if (mpfr_compare (res1, ref1)) { fprintf (stderr, "Error for %s(a, a, a) for a=%e\n", foo, mpfr_get_d (ref2)); fprintf (stderr, "expected %e, got %e\n", mpfr_get_d (ref1), @@ -114,6 +120,230 @@ void test3 (char *foo, mp_prec_t prec, mp_rnd_t rnd) mpfr_clear (res1); } +void test4 (char *foo, mp_prec_t prec, mp_rnd_t rnd) +{ + mpfr_t ref, op1,op2,op3,cop1,cop2,cop3, top1,top2,top3; + mpfr_t res; + int i,j,k; + +#ifdef DEBUG + printf("checking %s\n", foo); +#endif + mpfr_init2 (ref, prec); + mpfr_init2 (op1, prec); + mpfr_init2 (op2, prec); + mpfr_init2 (op3, prec); + mpfr_init2 (cop1, prec); + mpfr_init2 (cop2, prec); + mpfr_init2 (cop3, prec); + mpfr_init2 (top1, prec); + mpfr_init2 (top2, prec); + mpfr_init2 (top3, prec); + mpfr_init2 (res, prec); + + /* for each variable, consider each of the following 6 possibilities: + NaN, +Infinity, -Infinity, +0, -0 or a random number */ + + for (i=0; i<6; i++) + { + + if (i==0) MPFR_SET_NAN(op1); + if (i==1) mpfr_set_d (op1, 1.0/0.0, GMP_RNDN); + if (i==2) mpfr_set_d (op1, -1.0/0.0, GMP_RNDN); + if (i==3) mpfr_set_d (op1, 0.0, GMP_RNDN); + if (i==4) mpfr_set_d (op1, -0.0, GMP_RNDN); + if (i==5) mpfr_random (op1); + + for (j=0; j<6; j++) + { + + if (j==0) MPFR_SET_NAN(op2); + if (j==1) mpfr_set_d (op2, 1.0/0.0, GMP_RNDN); + if (j==2) mpfr_set_d (op2, -1.0/0.0, GMP_RNDN); + if (j==3) mpfr_set_d (op2, 0.0, GMP_RNDN); + if (j==4) mpfr_set_d (op2, -0.0, GMP_RNDN); + if (j==5) mpfr_random (op2); + + for (k=0; k<6; k++) + { + + if (k==0) MPFR_SET_NAN(op3); + if (k==1) mpfr_set_d (op3, 1.0/0.0, GMP_RNDN); + if (k==2) mpfr_set_d (op3, -1.0/0.0, GMP_RNDN); + if (k==3) mpfr_set_d (op3, 0.0, GMP_RNDN); + if (k==4) mpfr_set_d (op3, -0.0, GMP_RNDN); + if (k==5) mpfr_random (op3); + + mpfr_set (top1, op1, rnd); + mpfr_set (top2, op2, rnd); + mpfr_set (top3, op3, rnd); + + /* reference call: foo(s, a, b, c) */ + testfunc (ref, op1, op2, op3, rnd); + + /* foo(a, a, b, c) */ + mpfr_set (res, op1, rnd); /* exact operation */ + testfunc (res, res, op2, op3, rnd); + + if (mpfr_compare (res, ref)) + { + fprintf (stderr, + "Error for %s(a, a, b, c) for a=%e, b=%e, c=%e\n", + foo, + mpfr_get_d (op1), mpfr_get_d (op2), mpfr_get_d (op3)); + fprintf (stderr, "expected %e, got %e\n", mpfr_get_d (ref), + mpfr_get_d (res)); + exit (1); + } + + /* foo(b, a, b, c) */ + mpfr_set (res, op2, rnd); + testfunc (res, op1, res, op3, rnd); + + if (mpfr_compare (res, ref)) + { + fprintf (stderr, + "Error for %s(b, a, b, c) for a=%e, b=%e, c=%e\n", + foo, + mpfr_get_d (op1), mpfr_get_d (op2), mpfr_get_d (op3)); + fprintf (stderr, "expected %e, got %e\n", mpfr_get_d (ref), + mpfr_get_d (res)); + exit (1); + } + + /* foo(c, a, b, c) */ + mpfr_set (res, op3, rnd); + testfunc (res, op1, op2, res, rnd); + + if (mpfr_compare (res, ref)) + { + fprintf (stderr, + "Error for %s(c, a, b, c) for a=%e, b=%e, c=%e\n", + foo, + mpfr_get_d (op1), mpfr_get_d (op2), mpfr_get_d (op3)); + fprintf (stderr, "expected %e, got %e\n", mpfr_get_d (ref), + mpfr_get_d (res)); + exit (1); + } + + /* foo(a, a, a,c) */ + mpfr_set (op2, op1, rnd); + testfunc (ref, op1, op2, op3, rnd); + mpfr_set (res, op1, rnd); + testfunc (res, res, res, op3, rnd); + if (mpfr_compare (res, ref)) + { + fprintf (stderr, + "Error for %s(a, a, a, c) for a=%e, a=%e, c=%e\n", + foo, + mpfr_get_d (op1), mpfr_get_d (op2), mpfr_get_d (op3)); + fprintf (stderr, "expected %e, got %e\n", mpfr_get_d (ref), + mpfr_get_d (res)); + exit (1); + } + + mpfr_set (op1, top1, rnd); + mpfr_set (op2, top2, rnd); + mpfr_set (op3, top3, rnd); + + /* foo(a, a, b,a) */ + mpfr_set (op3, op1, rnd); + testfunc (ref, op1, op2, op3, rnd); + mpfr_set (res, op1, rnd); + testfunc (res, res, op2, res, rnd); + if (mpfr_compare (res, ref)) + { + fprintf (stderr, + "Error for %s(a, a, b, a) for a=%e, a=%e, c=%e\n", + foo, + mpfr_get_d (op1), mpfr_get_d (op2), mpfr_get_d (op3)); + fprintf (stderr, "expected %e, got %e\n", mpfr_get_d (ref), + mpfr_get_d (res)); + exit (1); + } + + mpfr_set (op1, top1, rnd); + mpfr_set (op2, top2, rnd); + mpfr_set (op3, top3, rnd); + + /* foo(b, a, b, b) */ + mpfr_set (op3, op2, rnd); + testfunc (ref, op1, op2, op3, rnd); + mpfr_set (res, op2, rnd); + testfunc (res, op1, res, res, rnd); + if (mpfr_compare (res, ref)) + { + fprintf (stderr, + "Error for %s(b, a, b, b) for a=%e, a=%e, c=%e\n", + foo, + mpfr_get_d (op1), mpfr_get_d (op2), mpfr_get_d (op3)); + fprintf (stderr, "expected %e, got %e\n", mpfr_get_d (ref), + mpfr_get_d (res)); + exit (1); + } + + MPFR_CLEAR_FLAGS(op1); + MPFR_CLEAR_FLAGS(op2); + MPFR_CLEAR_FLAGS(op3); + + mpfr_set (cop1, top1, rnd); + mpfr_set (cop2, top2, rnd); + mpfr_set (cop3, top3, rnd); + + mpfr_set (cop2, cop1, rnd); + mpfr_set (cop3, cop1, rnd); + testfunc (ref, cop1, cop2, cop3 ,rnd); + mpfr_set (res, cop1, rnd); + testfunc (res, res, res, res, rnd); + if (mpfr_compare (res, ref)) + { + fprintf (stderr, + "Error for %s(a, a, a, a) for a=%e, a=%e, a=%e\n", + foo, + mpfr_get_d (cop1), mpfr_get_d (cop2), mpfr_get_d (cop3)); + fprintf (stderr, "expected %e, got %e\n", mpfr_get_d (ref), + mpfr_get_d (res)); + exit (1); + } + /* + mpfr_set (op1, top1, rnd); + mpfr_set (op2, top2, rnd); + mpfr_set (op3, top3, rnd); + + mpfr_set (op2, op1, rnd); + mpfr_set (op3, op1, rnd); + testfunc (ref, op1, op2, op3 ,rnd); + mpfr_set (res, op1, rnd); + testfunc (res, res, res, res, rnd); + if (mpfr_compare (res, ref)) + { + fprintf (stderr, + "Error for %s(a, a, a, a) for a=%e, a=%e, a=%e\n", + foo, + mpfr_get_d (op1), mpfr_get_d (op2), mpfr_get_d (op3)); + fprintf (stderr, "expected %e, got %e\n", mpfr_get_d (ref), + mpfr_get_d (res)); + exit (1); + } + */ + } + } + } + + mpfr_clear (ref); + mpfr_clear (op1); + mpfr_clear (op2); + mpfr_clear (op3); + mpfr_clear (cop1); + mpfr_clear (cop2); + mpfr_clear (cop3); + mpfr_clear (top1); + mpfr_clear (top2); + mpfr_clear (top3); + mpfr_clear (res); + +} + void test2ui (char *foo, mp_prec_t prec, mp_rnd_t rnd) { mpfr_t ref1, ref2; @@ -129,36 +359,43 @@ void test2ui (char *foo, mp_prec_t prec, mp_rnd_t rnd) mpfr_init2 (ref2, prec); mpfr_init2 (res1, prec); - /* ref2 can be NaN, +Inf, -Inf, +0, -0 or any number - ref3 can be 0 or any number */ - for (i=0; i<12; i++) { - if (i%6==0) MPFR_SET_NAN(ref2); - if (i%6==1) mpfr_set_d (ref2, 1.0/0.0, GMP_RNDN); - if (i%6==2) mpfr_set_d (ref2, -1.0/0.0, GMP_RNDN); - if (i%6==3) mpfr_set_d (ref2, 0.0, GMP_RNDN); - if (i%6==4) mpfr_set_d (ref2, -0.0, GMP_RNDN); - if (i%6==5) mpfr_random (ref2); - - if (i/6==0) ref3=0; - else { - mpn_random (c, 1); - ref3 = (unsigned int) c[0]; - } - /* reference call: foo(a, b, c) */ - testfunc (ref1, ref2, ref3, rnd); - /* foo(a, a, c) */ - mpfr_set (res1, ref2, rnd); /* exact operation */ - testfunc (res1, res1, ref3, rnd); - if (mpfr_compare (res1, ref1)) { - fprintf (stderr, "Error for %s(a, a, c) for a=%e c=%u\n", foo, + /* ref2 can be NaN, +Inf, -Inf, +0, -0 or any number + ref3 can be 0 or any number */ + for (i=0; i<12; i++) + { + if (i%6==0) MPFR_SET_NAN(ref2); + if (i%6==1) mpfr_set_d (ref2, 1.0/0.0, GMP_RNDN); + if (i%6==2) mpfr_set_d (ref2, -1.0/0.0, GMP_RNDN); + if (i%6==3) mpfr_set_d (ref2, 0.0, GMP_RNDN); + if (i%6==4) mpfr_set_d (ref2, -0.0, GMP_RNDN); + if (i%6==5) mpfr_random (ref2); + + if (i/6==0) + ref3=0; + else + { + mpn_random (c, 1); + ref3 = (unsigned int) c[0]; + } + + /* reference call: foo(a, b, c) */ + testfunc (ref1, ref2, ref3, rnd); + + /* foo(a, a, c) */ + mpfr_set (res1, ref2, rnd); /* exact operation */ + testfunc (res1, res1, ref3, rnd); + + if (mpfr_compare (res1, ref1)) + { + fprintf (stderr, "Error for %s(a, a, c) for a=%e c=%u\n", foo, mpfr_get_d (ref2), ref3); - fprintf (stderr, "expected %e, got %e\n", mpfr_get_d (ref1), + fprintf (stderr, "expected %e, got %e\n", mpfr_get_d (ref1), mpfr_get_d (res1)); - exit (1); + exit (1); + } } - } mpfr_clear (ref1); mpfr_clear (ref2); @@ -357,30 +594,47 @@ void test3a (char *foo, mp_prec_t prec, mp_rnd_t rnd) mpfr_clear (res2); } -int main () +int +main (void) { - testfunc = mpfr_add; test3 ("mpfr_add", 53, GMP_RNDN); - testfunc = mpfr_add_ui; test2ui ("mpfr_add_ui", 53, GMP_RNDN); + testfunc = (void*) mpfr_add; test3 ("mpfr_add", 53, GMP_RNDN); + testfunc = (void*) mpfr_add_ui; test2ui ("mpfr_add_ui", 53, GMP_RNDN); testfunc = mpfr_agm; test3 ("mpfr_agm", 53, GMP_RNDN); testfunc = mpfr_ceil; test2 ("mpfr_ceil", 53, GMP_RNDN); - testfunc = mpfr_div; test3 ("mpfr_div", 53, GMP_RNDN); - testfunc = mpfr_div_2exp; test2ui ("mpfr_div_2exp", 53, GMP_RNDN); + testfunc = (void*) mpfr_div; test3 ("mpfr_div", 53, GMP_RNDN); + testfunc = (void*) mpfr_div_2exp; test2ui ("mpfr_div_2exp", 53, GMP_RNDN); testfunc = (void*) mpfr_div_ui; test2ui ("mpfr_div_ui", 53, GMP_RNDN); testfunc = (void*) mpfr_exp; test2 ("mpfr_exp", 53, GMP_RNDN); testfunc = mpfr_floor; test2 ("mpfr_floor", 53, GMP_RNDN); testfunc = (void*) mpfr_log; test2 ("mpfr_log", 53, GMP_RNDN); - testfunc = mpfr_mul; test3 ("mpfr_mul", 53, GMP_RNDN); - testfunc = mpfr_mul_2exp; test2ui ("mpfr_mul_2exp", 53, GMP_RNDN); - testfunc = mpfr_mul_ui; test2ui ("mpfr_mul_ui", 53, GMP_RNDN); - testfunc = mpfr_neg; test2 ("mpfr_neg", 53, GMP_RNDN); + testfunc = (void*) mpfr_mul; test3 ("mpfr_mul", 53, GMP_RNDN); + testfunc = (void*) mpfr_mul_2exp; test2ui ("mpfr_mul_2exp", 53, GMP_RNDN); + testfunc = (void*) mpfr_mul_ui; test2ui ("mpfr_mul_ui", 53, GMP_RNDN); + testfunc = (void*) mpfr_neg; test2 ("mpfr_neg", 53, GMP_RNDN); testfunc = (void*) mpfr_pow_ui; test2ui ("mpfr_pow_ui", 53, GMP_RNDN); testfunc = mpfr_reldiff; test3 ("mpfr_reldiff", 53, GMP_RNDN); - testfunc = (void*) mpfr_sin_cos; test3a ("mpfr_sin_cos", 53, GMP_RNDN); - testfunc = mpfr_sub; test3 ("mpfr_sub", 53, GMP_RNDN); - testfunc = mpfr_sub_ui; test2ui ("mpfr_sub_ui", 53, GMP_RNDN); + testfunc = (void*) mpfr_sub; test3 ("mpfr_sub", 53, GMP_RNDN); + testfunc = (void*) mpfr_sub_ui; test2ui ("mpfr_sub_ui", 53, GMP_RNDN); testfunc = (void*) mpfr_sqrt; test2 ("mpfr_sqrt", 53, GMP_RNDN); - testfunc = mpfr_ui_div; testui2 ("mpfr_ui_div", 53, GMP_RNDN); - testfunc = mpfr_ui_sub; testui2 ("mpfr_ui_sub", 53, GMP_RNDN); + testfunc = (void*) mpfr_ui_div; testui2 ("mpfr_ui_div", 53, GMP_RNDN); + testfunc = (void*) mpfr_ui_sub; testui2 ("mpfr_ui_sub", 53, GMP_RNDN); testfunc = mpfr_trunc; test2 ("mpfr_trunc", 53, GMP_RNDN); + testfunc = (void*) mpfr_asin; test2 ("mpfr_asin", 53, GMP_RNDN); + testfunc = (void*) mpfr_atan; test2 ("mpfr_atan", 53, GMP_RNDN); + testfunc = (void*) mpfr_sinh; test2 ("mpfr_sinh", 53, GMP_RNDN); + testfunc = (void*) mpfr_cosh; test2 ("mpfr_cosh", 53, GMP_RNDN); + testfunc = (void*) mpfr_tanh; test2 ("mpfr_tanh", 53, GMP_RNDN); + testfunc = (void*) mpfr_asinh; test2 ("mpfr_asinh", 53, GMP_RNDN); + testfunc = (void*) mpfr_acosh; test2 ("mpfr_acosh", 53, GMP_RNDN); + testfunc = (void*) mpfr_atanh; test2 ("mpfr_atanh", 53, GMP_RNDN); + testfunc = (void*) mpfr_exp2; test2 ("mpfr_exp2", 53, GMP_RNDN); + testfunc = (void*) mpfr_cos; test2 ("mpfr_cos", 53, GMP_RNDN); + testfunc = (void*) mpfr_sin; test2 ("mpfr_sin", 53, GMP_RNDN); + testfunc = (void*) mpfr_tan; test2 ("mpfr_tan", 53, GMP_RNDN); + testfunc = (void*) mpfr_log10; test2 ("mpfr_log10", 53, GMP_RNDN); + testfunc = (void*) mpfr_log2; test2 ("mpfr_log2", 53, GMP_RNDN); + testfunc = (void*) mpfr_pow; test3 ("mpfr_pow", 53, GMP_RNDN); + testfunc = (void*) mpfr_fma; test4 ("mpfr_fma", 53, GMP_RNDN); return 0; } + diff --git a/mpfr/tests/tabs.c b/mpfr/tests/tabs.c index 341ea516a..8b3a90cab 100644 --- a/mpfr/tests/tabs.c +++ b/mpfr/tests/tabs.c @@ -1,45 +1,99 @@ /* Test file for mpfr_abs. -Copyright (C) 2000 Free Software Foundation. +Copyright (C) 2000, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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 <stdio.h> #include <stdlib.h> +#include <math.h> #include "gmp.h" #include "mpfr.h" #include "mpfr-test.h" #define Infp (1/0.) -extern int isnan(); +void check_inexact _PROTO((void)); -int main(int argc, char *argv[]) +void +check_inexact () +{ + mp_prec_t p, q; + mpfr_t x, y, absx; + mp_rnd_t rnd; + int inexact, cmp; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (absx); + + for (p=1; p<500; p++) + { + mpfr_set_prec (x, p); + mpfr_set_prec (absx, p); + mpfr_random (x); + if (rand () % 2) + { + mpfr_set (absx, x, GMP_RNDN); + mpfr_neg (x, x, GMP_RNDN); + } + else + mpfr_set (absx, x, GMP_RNDN); + for (q=1; q<2*p; q++) + { + mpfr_set_prec (y, q); + for (rnd=0; rnd<4; rnd++) + { + inexact = mpfr_abs (y, x, rnd); + cmp = mpfr_cmp (y, absx); + if (((inexact == 0) && (cmp != 0)) || + ((inexact > 0) && (cmp <= 0)) || + ((inexact < 0) && (cmp >= 0))) + { + fprintf (stderr, "Wrong inexact flag: expected %d, got %d\n", cmp, inexact); + printf ("x="); mpfr_print_raw (x); putchar ('\n'); + printf ("absx="); mpfr_print_raw (absx); putchar ('\n'); + printf ("y="); mpfr_print_raw (y); putchar ('\n'); + exit (1); + } + } + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (absx); +} + +int +main (int argc, char *argv[]) { mpfr_t x; int n, k, rnd; double d, dd; #ifdef __mips - /* to get denormalized numbers on IRIX64 */ - union fpc_csr exp; - exp.fc_word = get_fpc_csr(); - exp.fc_struct.flush = 0; - set_fpc_csr(exp.fc_word); + /* to get denormalized numbers on IRIX64 */ + union fpc_csr exp; + exp.fc_word = get_fpc_csr(); + exp.fc_struct.flush = 0; + set_fpc_csr(exp.fc_word); #endif + check_inexact (); + mpfr_init2(x, 53); mpfr_set_d(x, 1.0, GMP_RNDN); @@ -85,5 +139,6 @@ int main(int argc, char *argv[]) } mpfr_clear(x); + return 0; } diff --git a/mpfr/tests/tacosh.c b/mpfr/tests/tacosh.c new file mode 100644 index 000000000..7d518e7d7 --- /dev/null +++ b/mpfr/tests/tacosh.c @@ -0,0 +1,38 @@ +/* Test file for mpfr_acosh. + +Copyright (C) 2001 Free Software Foundation. +Adapted from tarctan.c. + +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 <stdio.h> +#include <stdlib.h> +#include <gmp.h> +#include <mpfr.h> + +#define TEST_FUNCTION mpfr_acosh +#define RAND_FUNCTION(x) (mpfr_random (x), mpfr_ui_div (x, 1, x, GMP_RNDN)) +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + test_generic (1, 100, 25); + + return 0; +} diff --git a/mpfr/tests/tadd.c b/mpfr/tests/tadd.c index 562d9b853..a500c9397 100644 --- a/mpfr/tests/tadd.c +++ b/mpfr/tests/tadd.c @@ -1,20 +1,20 @@ /* Test file for mpfr_add and mpfr_sub. -Copyright (C) 1999 Free Software Foundation. +Copyright (C) 1999-2001 Free Software Foundation. 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ @@ -29,7 +29,6 @@ MA 02111-1307, USA. */ #include "mpfr-impl.h" #include "mpfr-test.h" -extern int isnan(); extern int getpid(); void check _PROTO((double, double, mp_rnd_t, unsigned int, unsigned int, unsigned int, double)); void checknan _PROTO((double, double, mp_rnd_t, unsigned int, unsigned int, unsigned int)); @@ -40,6 +39,9 @@ void check2 _PROTO((double, int, double, int, int, int)); void check2a _PROTO((double, int, double, int, int, int, char *)); void check64 _PROTO((void)); void check_same _PROTO((void)); +void check_case_1b _PROTO((void)); +void check_case_2 _PROTO((void)); +void check_inexact _PROTO((void)); /* checks that x+y gives the same results in double and with mpfr with 53 bits of precision */ @@ -61,7 +63,7 @@ unsigned int py, unsigned int pz, double z1) if (z1==0.0) z1=x+y; else cert=1; z2 = mpfr_get_d(zz); mpfr_set_d (yy, z2, GMP_RNDN); - if (!mpfr_cmp (xx, yy) && cert && z1!=z2 && !(isnan(z1) && isnan(z2))) { + if (!mpfr_cmp (zz, yy) && cert && z1!=z2 && !(isnan(z1) && isnan(z2))) { printf("expected sum is %1.20e, got %1.20e\n",z1,z2); printf("mpfr_add failed for x=%1.20e y=%1.20e with rnd_mode=%s\n", x, y, mpfr_print_rnd_mode(rnd_mode)); @@ -218,7 +220,63 @@ void check64 () { mpfr_t x, t, u; - mpfr_init(x); mpfr_init(t); mpfr_init(u); + mpfr_init (x); + mpfr_init (t); + mpfr_init (u); + + mpfr_set_prec (x, 29); + mpfr_set_str_raw (x, "1.1101001000101111011010010110e-3"); + mpfr_set_prec (t, 58); + mpfr_set_str_raw (t, "0.11100010011111001001100110010111110110011000000100101E-1"); + mpfr_set_prec (u, 29); + mpfr_add (u, x, t, GMP_RNDD); + mpfr_set_str_raw (t, "1.0101011100001000011100111110e-1"); + if (mpfr_cmp (u, t)) + { + fprintf (stderr, "mpfr_add(u, x, t) failed for prec(x)=29, prec(t)=58\n"); + printf ("expected "); mpfr_out_str (stdout, 2, 29, t, GMP_RNDN); + putchar ('\n'); + printf ("got "); mpfr_out_str (stdout, 2, 29, u, GMP_RNDN); + putchar ('\n'); + exit(1); + } + + mpfr_set_prec (x, 4); + mpfr_set_str_raw (x, "-1.0E-2"); + mpfr_set_prec (t, 2); + mpfr_set_str_raw (t, "-1.1e-2"); + mpfr_set_prec (u, 2); + mpfr_add (u, x, t, GMP_RNDN); + if (MPFR_MANT(u)[0] << 2) + { + fprintf (stderr, "result not normalized for prec=2\n"); + mpfr_print_raw (u); putchar ('\n'); + exit (1); + } + mpfr_set_str_raw (t, "-1.0e-1"); + if (mpfr_cmp (u, t)) + { + fprintf (stderr, "mpfr_add(u, x, t) failed for prec(x)=4, prec(t)=2\n"); + printf ("expected -1.0e-1\n"); + printf ("got "); mpfr_out_str (stdout, 2, 4, u, GMP_RNDN); + putchar ('\n'); + exit (1); + } + + mpfr_set_prec (x, 8); + mpfr_set_str_raw (x, "-0.10011010"); /* -77/128 */ + mpfr_set_prec (t, 4); + mpfr_set_str_raw (t, "-1.110e-5"); /* -7/128 */ + mpfr_set_prec (u, 4); + mpfr_add (u, x, t, GMP_RNDN); /* should give -5/8 */ + mpfr_set_str_raw (t, "-1.010e-1"); + if (mpfr_cmp (u, t)) { + fprintf (stderr, "mpfr_add(u, x, t) failed for prec(x)=8, prec(t)=4\n"); + printf ("expected -1.010e-1\n"); + printf ("got "); mpfr_out_str (stdout, 2, 4, u, GMP_RNDN); + putchar ('\n'); + exit (1); + } mpfr_set_prec (x, 112); mpfr_set_prec (t, 98); mpfr_set_prec (u, 54); mpfr_set_str_raw (x, "-0.11111100100000000011000011100000101101010001000111E-401"); @@ -283,7 +341,7 @@ void check64 () } if ((MPFR_MANT(u)[(MPFR_PREC(u)-1)/mp_bits_per_limb] & ((mp_limb_t)1<<(mp_bits_per_limb-1)))==0) { - printf("Error in mpfr_sub: result is not msb-normalized\n"); exit(1); + printf("Error in mpfr_sub: result is not msb-normalized (1)\n"); exit(1); } mpfr_set_prec(x, 65); mpfr_set_prec(t, 65); mpfr_set_prec(u, 65); mpfr_set_str_raw(x, "0.10011010101000110101010000000011001001001110001011101011111011101E623"); @@ -336,9 +394,35 @@ void check64 () mpfr_sub(u, x, t, GMP_RNDN); if ((MPFR_MANT(u)[(MPFR_PREC(u)-1)/mp_bits_per_limb] & ((mp_limb_t)1<<(mp_bits_per_limb-1)))==0) { - printf("Error in mpfr_sub: result is not msb-normalized\n"); exit(1); + printf("Error in mpfr_sub: result is not msb-normalized (2)\n"); exit(1); } + /* bug found by Nathalie Revol, 21 March 2001 */ + mpfr_set_prec (x, 65); + mpfr_set_prec (t, 65); + mpfr_set_prec (u, 65); + mpfr_set_str_raw (x, "0.11100100101101001100111011111111110001101001000011101001001010010E-35"); + mpfr_set_str_raw (t, "0.10000000000000000000000000000000000001110010010110100110011110000E1"); + mpfr_sub (u, t, x, GMP_RNDU); + if ((MPFR_MANT(u)[(MPFR_PREC(u)-1)/mp_bits_per_limb] & + ((mp_limb_t)1<<(mp_bits_per_limb-1)))==0) { + fprintf(stderr, "Error in mpfr_sub: result is not msb-normalized (3)\n"); + exit (1); + } + + /* bug found by Fabrice Rouillier, 27 Mar 2001 */ + mpfr_set_prec (x, 107); + mpfr_set_prec (t, 107); + mpfr_set_prec (u, 107); + mpfr_set_str_raw (x, "0.10111001001111010010001000000010111111011011011101000001001000101000000000000000000000000000000000000000000E315"); + mpfr_set_str_raw (t, "0.10000000000000000000000000000000000101110100100101110110000001100101011111001000011101111100100100111011000E350"); + mpfr_sub (u, x, t, GMP_RNDU); + if ((MPFR_MANT(u)[(MPFR_PREC(u)-1)/mp_bits_per_limb] & + ((mp_limb_t)1<<(mp_bits_per_limb-1)))==0) { + fprintf(stderr, "Error in mpfr_sub: result is not msb-normalized (4)\n"); + exit (1); + } + /* checks that NaN flag is correctly reset */ mpfr_set_d (t, 1.0, GMP_RNDN); mpfr_set_d (u, 1.0, GMP_RNDN); @@ -352,6 +436,88 @@ void check64 () mpfr_clear(x); mpfr_clear(t); mpfr_clear(u); } +/* check case when c does not overlap with a, but both b and c count + for rounding */ +void check_case_1b (void) +{ + mpfr_t a, b, c; + unsigned int prec_a, prec_b, prec_c, dif; + + mpfr_init (a); + mpfr_init (b); + mpfr_init (c); + + for (prec_a = 1; prec_a <= 64; prec_a++) + { + mpfr_set_prec (a, prec_a); + for (prec_b = prec_a + 1; prec_b <= 64; prec_b++) + { + dif = prec_b - prec_a; + mpfr_set_prec (b, prec_b); + /* b = 1 - 2^(-prec_a) + 2^(-prec_b) */ + mpfr_set_ui (b, 1, GMP_RNDN); + mpfr_div_2exp (b, b, dif, GMP_RNDN); + mpfr_sub_ui (b, b, 1, GMP_RNDN); + mpfr_div_2exp (b, b, prec_a, GMP_RNDN); + mpfr_add_ui (b, b, 1, GMP_RNDN); + for (prec_c = dif; prec_c <= 64; prec_c++) + { + /* c = 2^(-prec_a) - 2^(-prec_b) */ + mpfr_set_prec (c, prec_c); + mpfr_set_si (c, -1, GMP_RNDN); + mpfr_div_2exp (c, c, dif, GMP_RNDN); + mpfr_add_ui (c, c, 1, GMP_RNDN); + mpfr_div_2exp (c, c, prec_a, GMP_RNDN); + mpfr_add (a, b, c, GMP_RNDN); + if (mpfr_cmp_ui (a, 1) != 0) + { + fprintf (stderr, "case (1b) failed for prec_a=%u, prec_b=%u, prec_c=%u\n", prec_a, prec_b, prec_c); + printf("b="); mpfr_print_raw(b); putchar('\n'); + printf("c="); mpfr_print_raw(c); putchar('\n'); + printf("a="); mpfr_print_raw(a); putchar('\n'); + exit (1); + } + } + } + } + + mpfr_clear (a); + mpfr_clear (b); + mpfr_clear (c); +} + +/* check case when c overlaps with a */ +void check_case_2 (void) +{ + mpfr_t a, b, c, d; + + mpfr_init2 (a, 300); + mpfr_init2 (b, 800); + mpfr_init2 (c, 500); + mpfr_init2 (d, 800); + + mpfr_set_str_raw(a, "1E110"); /* a = 2^110 */ + mpfr_set_str_raw(b, "1E900"); /* b = 2^900 */ + mpfr_set_str_raw(c, "1E500"); /* c = 2^500 */ + mpfr_add(c, c, a, GMP_RNDZ); /* c = 2^500 + 2^110 */ + mpfr_sub(d, b, c, GMP_RNDZ); /* d = 2^900 - 2^500 - 2^110 */ + mpfr_add(b, b, c, GMP_RNDZ); /* b = 2^900 + 2^500 + 2^110 */ + mpfr_add(a, b, d, GMP_RNDZ); /* a = 2^901 */ + if (mpfr_cmp_ui_2exp (a, 1, 901)) + { + fprintf (stderr, "b + d fails for b=2^900+2^500+2^110, d=2^900-2^500-2^110\n"); + fprintf (stderr, "expected 1.0e901, got "); + mpfr_out_str (stderr, 2, 0, a, GMP_RNDN); + fprintf (stderr, "\n"); + exit (1); + } + + mpfr_clear (a); + mpfr_clear (b); + mpfr_clear (c); + mpfr_clear (d); +} + /* checks when source and destination are equal */ void check_same () { @@ -368,7 +534,99 @@ void check_same () #define check53(x, y, r, z) check(x, y, r, 53, 53, 53, z) #define check53nan(x, y, r) checknan(x, y, r, 53, 53, 53); -int main(argc,argv) int argc; char *argv[]; +#define MAX_PREC 100 + +void +check_inexact () +{ + mpfr_t x, y, z, u; + mp_prec_t px, py, pu, pz; + int inexact, cmp; + mp_rnd_t rnd; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + mpfr_init (u); + + mpfr_set_prec (x, 1); + mpfr_set_str_raw (x, "0.1E-4"); + mpfr_set_prec (u, 33); + mpfr_set_str_raw (u, "0.101110100101101100000000111100000E-1"); + mpfr_set_prec (y, 31); + if ((inexact = mpfr_add (y, x, u, GMP_RNDN))) + { + fprintf (stderr, "Wrong inexact flag (2): expected 0, got %d\n", inexact); + exit (1); + } + + mpfr_set_prec (x, 1); + mpfr_set_str_raw (x, "0.1E-4"); + mpfr_set_prec (u, 33); + mpfr_set_str_raw (u, "0.101110100101101100000000111100000E-1"); + mpfr_set_prec (y, 28); + if ((inexact = mpfr_add (y, x, u, GMP_RNDN))) + { + fprintf (stderr, "Wrong inexact flag (1): expected 0, got %d\n", inexact); + exit (1); + } + + for (px=1; px<MAX_PREC; px++) + { + mpfr_set_prec (x, px); + mpfr_random (x); + for (pu=1; pu<MAX_PREC; pu++) + { + mpfr_set_prec (u, pu); + mpfr_random (u); + for (py=1; py<MAX_PREC; py++) + { + mpfr_set_prec (y, py); + pz = (mpfr_cmp_abs (x, u) >= 0) ? MPFR_EXP(x)-MPFR_EXP(u) + : MPFR_EXP(u)-MPFR_EXP(x); + /* x + u is exactly representable with precision + abs(EXP(x)-EXP(u)) + max(prec(x), prec(u)) + 1 */ + pz = pz + MAX(MPFR_PREC(x), MPFR_PREC(u)) + 1; + mpfr_set_prec (z, pz); + rnd = rand () % 4; + if (mpfr_add (z, x, u, rnd)) + { + fprintf (stderr, "z <- x + u should be exact\n"); + printf ("x="); mpfr_print_raw (x); putchar ('\n'); + printf ("u="); mpfr_print_raw (u); putchar ('\n'); + printf ("z="); mpfr_print_raw (z); putchar ('\n'); + exit (1); + } + for (rnd=0; rnd<4; rnd++) + { + inexact = mpfr_add (y, x, u, rnd); + cmp = mpfr_cmp (y, z); + if (((inexact == 0) && (cmp != 0)) || + ((inexact > 0) && (cmp <= 0)) || + ((inexact < 0) && (cmp >= 0))) + { + fprintf (stderr, "Wrong inexact flag for rnd=%s\n", + mpfr_print_rnd_mode(rnd)); + printf ("expected %d, got %d\n", cmp, inexact); + printf ("x="); mpfr_print_raw (x); putchar ('\n'); + printf ("u="); mpfr_print_raw (u); putchar ('\n'); + printf ("y= "); mpfr_print_raw (y); putchar ('\n'); + printf ("x+u="); mpfr_print_raw (z); putchar ('\n'); + exit (1); + } + } + } + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (u); +} + +int +main (int argc, char *argv[]) { int prec, rnd_mode; #ifdef TEST @@ -383,6 +641,9 @@ int main(argc,argv) int argc; char *argv[]; set_fpc_csr(exp.fc_word); #endif + check_inexact (); + check_case_1b (); + check_case_2 (); check64(); check(293607738.0, 1.9967571564050541e-5, GMP_RNDU, 64, 53, 53, 2.9360773800002003e8); @@ -554,6 +815,13 @@ int main(argc,argv) int argc; char *argv[]; GMP_RNDN, -1.90982880222349071e-121); check53nan(1/0., -1/0., GMP_RNDN); + + /* tests for particular cases (Vincent Lefevre, 22 Aug 2001) */ + check53(9007199254740992.0, 1.0, GMP_RNDN, 9007199254740992.0); + check53(9007199254740994.0, 1.0, GMP_RNDN, 9007199254740996.0); + check53(9007199254740992.0, -1.0, GMP_RNDN, 9007199254740991.0); + check53(9007199254740994.0, -1.0, GMP_RNDN, 9007199254740992.0); + check53(9007199254740996.0, -1.0, GMP_RNDN, 9007199254740996.0); #ifdef TEST /* Comparing to double precision using machine arithmetic */ @@ -605,6 +873,6 @@ int main(argc,argv) int argc; char *argv[]; check5(x, rnd); } #endif + return 0; } - diff --git a/mpfr/tests/tadd_ui.c b/mpfr/tests/tadd_ui.c new file mode 100644 index 000000000..cbf864eea --- /dev/null +++ b/mpfr/tests/tadd_ui.c @@ -0,0 +1,116 @@ +/* Test file for mpfr_add_ui + +Copyright (C) 2000, 2001 Free Software Foundation. + +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. */ + +/* #define DEBUG */ +/* #define VERBOSE */ + +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include "gmp.h" +#include "mpfr.h" +#include "mpfr-impl.h" +#ifdef __mips +#include <sys/fpu.h> +#endif + +void check3 _PROTO((double, unsigned long, unsigned int, double)); +void special _PROTO((void)); + +#define ABS(x) (((x)>0) ? (x) : (-x)) + +#define check(x,y,r) check3(x,y,r,0.0) + +/* checks that x+y gives the same results in double + and with mpfr with 53 bits of precision */ +void +check3 (double x, unsigned long y, unsigned int rnd_mode, double z1) +{ + double z2; mpfr_t xx,zz; + + mpfr_init2(xx, 53); + mpfr_init2(zz, 53); + mpfr_set_d(xx, x, rnd_mode); + mpfr_add_ui(zz, xx, y, rnd_mode); +#ifdef TEST + mpfr_set_machine_rnd_mode(rnd_mode); +#endif + if (z1==0.0) z1 = x+y; + z2 = mpfr_get_d(zz); + if (z1!=z2 && !(isnan(z1) && isnan(z2))) { + printf("expected sum is %1.20e, got %1.20e\n",z1,z2); + printf("mpfr_add_ui failed for x=%1.20e y=%lu with rnd_mode=%s\n", + x, y, mpfr_print_rnd_mode(rnd_mode)); + exit(1); + } + mpfr_clear(xx); mpfr_clear(zz); +} + +void special (void) +{ + mpfr_t x, y; + + mpfr_init2 (x, 63); + mpfr_init2 (y, 63); + mpfr_set_str_raw (x, "0.110100000000000001110001110010111111000000000101100011100100011"); + mpfr_add_ui (y, x, 1, GMP_RNDD); + mpfr_clear (x); + mpfr_clear (y); +} + +int main(argc,argv) int argc; char *argv[]; +{ +#ifdef TEST + double x; unsigned long y, N; int i,rnd_mode,rnd; +#ifdef __mips + /* to get denormalized numbers on IRIX64 */ + union fpc_csr exp; + exp.fc_word = get_fpc_csr(); + exp.fc_struct.flush = 0; + set_fpc_csr(exp.fc_word); +#endif + + srand(getpid()); + N = (argc<2) ? 1000000 : atoi(argv[1]); + rnd_mode = (argc<3) ? -1 : atoi(argv[2]); + for (i=0;i<1000000;i++) { + x = drand48(); + y = lrand48(); + if (ABS(x)>2.2e-307 && x+y<1.7e+308 && x+y>-1.7e308) { + /* avoid denormalized numbers and overflows */ + rnd = (rnd_mode==-1) ? lrand48()%4 : rnd_mode; + check(x, y, rnd); + } + } +#endif + special (); + check3(-1.716113812768534e-140, 1271212614, GMP_RNDZ, 1.27121261399999976e9); + check3(1.22191250737771397120e+20, 948002822, GMP_RNDN, + 122191250738719408128.0); + check3(-6.72658901114033715233e-165, 2000878121, GMP_RNDZ, + 2.0008781209999997615e9); + check3(-2.0769715792901673e-5, 880524, GMP_RNDN, 8.8052399997923023e5); + check3(1/0., 2394875, GMP_RNDN, 1/0.); + check3(-1/0., 2394875, GMP_RNDN, -1/0.); + check3(0./0., 2394875, GMP_RNDN, 0./0.); + return 0; +} + diff --git a/mpfr/tests/tagm.c b/mpfr/tests/tagm.c index e6c411677..01162d8da 100644 --- a/mpfr/tests/tagm.c +++ b/mpfr/tests/tagm.c @@ -1,20 +1,20 @@ /* Test file for mpfr_agm. -Copyright (C) 1999 Free Software Foundation. +Copyright (C) 1999, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ @@ -142,7 +142,9 @@ void slave (int N, int p) } -int main(int argc, char* argv[]) { +int +main (int argc, char* argv[]) +{ int N; if (argc==3) { /* tagm N p : N calculus with precision p*/ @@ -178,5 +180,6 @@ int main(int argc, char* argv[]) { } /* TODO : tests des infinis dans tagm.c */ + return 0; } diff --git a/mpfr/tests/tasin.c b/mpfr/tests/tasin.c new file mode 100644 index 000000000..3d48f2910 --- /dev/null +++ b/mpfr/tests/tasin.c @@ -0,0 +1,78 @@ +/* Test file for mpfr_asin. + +Copyright (C) 2001 Free Software Foundation. +Contributed by Mathieu Dutour. + +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 <stdio.h> +#include <stdlib.h> +#include <gmp.h> +#include <mpfr.h> + +int +main (void) +{ + unsigned int prec, err, yprec, n; + mp_rnd_t rnd; + mpfr_t x, y, z; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + + for (prec = 1; prec <= 100; prec++) + { + mpfr_set_prec (x, prec); + mpfr_set_prec (z, prec); + yprec = prec + 10; + + for (n = 0; n < 10; n++) + { + mpfr_random (x); + rnd = random () % 4; + mpfr_set_prec (y, yprec); + mpfr_asin (y, x, rnd); + err = (rnd == GMP_RNDN) ? yprec + 1 : yprec; + if (mpfr_can_round (y, err, rnd, rnd, prec)) + { + mpfr_round (y, rnd, prec); + mpfr_asin (z, x, rnd); + if (mpfr_cmp (y, z)) + { + printf ("results differ for x="); + mpfr_out_str (stdout, 2, prec, x, GMP_RNDN); + printf (" prec=%u rnd_mode=%s\n", prec, + mpfr_print_rnd_mode (rnd)); + printf (" got "); + mpfr_out_str (stdout, 2, prec, z, GMP_RNDN); + putchar ('\n'); + printf (" expected "); + mpfr_out_str (stdout, 2, prec, y, GMP_RNDN); + putchar ('\n'); + } + } + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + + return 0; +} diff --git a/mpfr/tests/tasinh.c b/mpfr/tests/tasinh.c new file mode 100644 index 000000000..5dcca7776 --- /dev/null +++ b/mpfr/tests/tasinh.c @@ -0,0 +1,50 @@ +/* Test file for mpfr_asinh. + +Copyright (C) 2001 Free Software Foundation. +Adapted from tarctan.c. + +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 <stdio.h> +#include <stdlib.h> +#include <gmp.h> +#include <mpfr.h> + +#define TEST_FUNCTION mpfr_asinh +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y; + + mpfr_init (x); + mpfr_init (y); + + mpfr_set_prec (x, 33); + mpfr_set_prec (y, 43); + mpfr_set_str_raw (x, "0.111001101100000110011001010000101"); + mpfr_asinh (y, x, GMP_RNDZ); + + test_generic (1, 100, 25); + + mpfr_clear (x); + mpfr_clear (y); + + return 0; +} diff --git a/mpfr/tests/tatan.c b/mpfr/tests/tatan.c new file mode 100644 index 000000000..0546d9dcc --- /dev/null +++ b/mpfr/tests/tatan.c @@ -0,0 +1,94 @@ +/* Test file for mpfr_arctan. + +Copyright (C) 2001 Free Software Foundation. +Written by Paul Zimmermann, INRIA Lorraine. + +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 <stdio.h> +#include <stdlib.h> +#include <gmp.h> +#include <mpfr.h> + +int mpfr_arctan_aux2 (mpfr_ptr, mpfr_srcptr, mp_rnd_t); + +int +main (int argc, char *argv[]) +{ + unsigned int prec, err, yprec, n, p0 = 1, p1 = 100, N = 10; + mp_rnd_t rnd; + mpfr_t x, y, z, t; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + mpfr_init (t); + + /* tarctan prec - perform one random computation with precision prec */ + if (argc >= 2) + { + p0 = p1 = atoi (argv[1]); + N = 1; + } + + for (prec = p0; prec <= p1; prec++) + { + mpfr_set_prec (x, prec); + mpfr_set_prec (z, prec); + mpfr_set_prec (t, prec); + yprec = prec + 10; + + for (n=0; n<N; n++) + { + mpfr_random (x); + rnd = random () % 4; + mpfr_set_prec (y, yprec); + mpfr_atan (y, x, rnd); + err = (rnd == GMP_RNDN) ? yprec + 1 : yprec; + if (mpfr_can_round (y, err, rnd, rnd, prec)) + { + mpfr_set (t, y, rnd); + mpfr_atan (z, x, rnd); + if (mpfr_cmp (t, z)) + { + printf ("results differ for x="); + mpfr_out_str (stdout, 2, prec, x, GMP_RNDN); + printf (" prec=%u rnd_mode=%s\n", prec, + mpfr_print_rnd_mode (rnd)); + printf (" got "); + mpfr_out_str (stdout, 2, prec, z, GMP_RNDN); + putchar ('\n'); + printf (" expected "); + mpfr_out_str (stdout, 2, prec, t, GMP_RNDN); + putchar ('\n'); + printf (" approximation was "); + mpfr_print_raw (y); + putchar ('\n'); + exit (1); + } + } + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (t); + + return 0; +} diff --git a/mpfr/tests/tatanh.c b/mpfr/tests/tatanh.c new file mode 100644 index 000000000..c982d8403 --- /dev/null +++ b/mpfr/tests/tatanh.c @@ -0,0 +1,37 @@ +/* Test file for mpfr_atanh. + +Copyright (C) 2001 Free Software Foundation. +Adapted from tarctan.c. + +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 <stdio.h> +#include <stdlib.h> +#include <gmp.h> +#include <mpfr.h> + +#define TEST_FUNCTION mpfr_atanh +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + test_generic (1, 100, 25); + + return 0; +} diff --git a/mpfr/tests/tcan_round.c b/mpfr/tests/tcan_round.c index 4d5fd0cb5..ffbb9023f 100644 --- a/mpfr/tests/tcan_round.c +++ b/mpfr/tests/tcan_round.c @@ -1,20 +1,20 @@ /* Test file for mpfr_can_round. -Copyright (C) 1999 Free Software Foundation. +Copyright (C) 1999, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ @@ -24,25 +24,37 @@ MA 02111-1307, USA. */ #include "gmp.h" #include "mpfr.h" -int main() +int +main (void) { mpfr_t x; /* checks that rounds to nearest sets the last bit to zero in case of equal distance */ - mpfr_init2(x, 59); - mpfr_set_str_raw(x, "-0.10010001010111000011110010111010111110000000111101100111111E663"); - if (mpfr_can_round(x, 54, GMP_RNDZ, GMP_RNDZ, 53) != 0) { - fprintf(stderr, "Error in mpfr_can_round\n"); exit(1); - } - - mpfr_set_str_raw(x, "-Inf"); - if (mpfr_can_round(x, 2000, GMP_RNDZ, GMP_RNDZ, 2000) != 0) { - fprintf(stderr, "Error in mpfr_can_round\n"); exit(1); - } - mpfr_clear(x); + mpfr_init2 (x, 59); + mpfr_set_str_raw (x, "-0.10010001010111000011110010111010111110000000111101100111111E663"); + if (mpfr_can_round (x, 54, GMP_RNDZ, GMP_RNDZ, 53) != 0) + { + fprintf (stderr, "Error (1) in mpfr_can_round\n"); + exit (1); + } + + mpfr_set_str_raw (x, "-Inf"); + if (mpfr_can_round (x, 2000, GMP_RNDZ, GMP_RNDZ, 2000) != 0) + { + fprintf (stderr, "Error (2) in mpfr_can_round\n"); + exit (1); + } + + mpfr_set_prec (x, 64); + mpfr_set_str_raw (x, "0.1011001000011110000110000110001111101011000010001110011000000000"); + if (mpfr_can_round (x, 65, GMP_RNDN, GMP_RNDN, 54)) + { + fprintf (stderr, "Error (3) in mpfr_can_round\n"); + exit (1); + } + + mpfr_clear (x); + return 0; } - - - diff --git a/mpfr/tests/tcmp.c b/mpfr/tests/tcmp.c index 3d033314d..98b7b4412 100644 --- a/mpfr/tests/tcmp.c +++ b/mpfr/tests/tcmp.c @@ -1,20 +1,20 @@ /* Test file for mpfr_cmp. -Copyright (C) 1999 Free Software Foundation. +Copyright (C) 1999, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ @@ -24,20 +24,34 @@ MA 02111-1307, USA. */ #include <math.h> #include "gmp.h" #include "mpfr.h" +#include "mpfr-impl.h" #include "mpfr-test.h" #define Infp 1/0. #define Infm -1/0. -extern int isnan(); - -int main() +int +main (void) { double x, y; mpfr_t xx, yy; int i, c; - mpfr_init2(xx, 65); mpfr_init2(yy, 65); + mpfr_init (xx); + mpfr_init (yy); + + mpfr_set_prec (xx, 2); + mpfr_set_prec (yy, 2); + mpfr_set_str_raw(xx, "-0.10E0"); + mpfr_set_str_raw(yy, "-0.10E0"); + if (mpfr_cmp (xx, yy)) + { + fprintf (stderr, "mpfr_cmp (xx, yy) returns non-zero for prec=2\n"); + exit (1); + } + + mpfr_set_prec (xx, 65); + mpfr_set_prec (yy, 65); mpfr_set_str_raw(xx, "0.10011010101000110101010000000011001001001110001011101011111011101E623"); mpfr_set_str_raw(yy, "0.10011010101000110101010000000011001001001110001011101011111011100E623"); if (mpfr_cmp2(xx,yy)!=64) { printf("Error (1) in mpfr_cmp\n"); exit(1); } @@ -149,5 +163,6 @@ int main() } mpfr_clear(xx); mpfr_clear(yy); + return 0; } diff --git a/mpfr/tests/tcmp2.c b/mpfr/tests/tcmp2.c index 4ddb16bea..568f5e860 100644 --- a/mpfr/tests/tcmp2.c +++ b/mpfr/tests/tcmp2.c @@ -1,20 +1,20 @@ /* Test file for mpfr_cmp2. -Copyright (C) 1999-2000 Free Software Foundation. +Copyright (C) 1999-2001 Free Software Foundation. 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ @@ -29,8 +29,123 @@ MA 02111-1307, USA. */ void tcmp2 (double, double, int); void special (void); +void worst_cases (void); +void set_bit (mpfr_t, unsigned int, int); -void tcmp2 (double x, double y, int i) +/* set bit n of x to b, where bit 0 is the most significant one */ +void +set_bit (mpfr_t x, unsigned int n, int b) +{ + unsigned l; + mp_size_t xn; + + xn = (MPFR_PREC(x) - 1) / mp_bits_per_limb; + l = n / mp_bits_per_limb; + n %= mp_bits_per_limb; + n = mp_bits_per_limb - 1 - n; + if (b) + MPFR_MANT(x)[xn - l] |= (mp_limb_t) 1 << n; + else + MPFR_MANT(x)[xn - l] &= ~((mp_limb_t) 1 << n); +} + +/* check that for x = 1.u 1 v 0^k low(x) + y = 1.u 0 v 1^k low(y) + mpfr_cmp2 (x, y) returns 1 + |u| + |v| + k for low(x) >= low(y), + and 1 + |u| + |v| + k + 1 otherwise */ +void +worst_cases () +{ + mpfr_t x, y; + unsigned int i, j, k, l, b, expected; + + mpfr_init2 (x, 200); + mpfr_init2 (y, 200); + + mpfr_set_ui (y, 1, GMP_RNDN); + for (i=1; i<MPFR_PREC(x); i++) + { + mpfr_set_ui (x, 1, GMP_RNDN); + mpfr_div_2exp (y, y, 1, GMP_RNDN); /* y = 1/2^i */ + + if ((l = mpfr_cmp2 (x, y)) != 1) + { + fprintf (stderr, "Error in mpfr_cmp2:\nx="); + mpfr_out_str (stderr, 2, 0, x, GMP_RNDN); + fprintf (stderr, "\ny="); + mpfr_out_str (stderr, 2, 0, y, GMP_RNDN); + fprintf (stderr, "\ngot %u instead of %u\n", l, 1); + exit(1); + } + + mpfr_add (x, x, y, GMP_RNDN); /* x = 1 + 1/2^i */ + if ((l = mpfr_cmp2 (x, y)) != 0) + { + fprintf (stderr, "Error in mpfr_cmp2:\nx="); + mpfr_out_str (stderr, 2, 0, x, GMP_RNDN); + fprintf (stderr, "\ny="); + mpfr_out_str (stderr, 2, 0, y, GMP_RNDN); + fprintf (stderr, "\ngot %u instead of %u\n", l, 0); + exit(1); + } + } + + for (i=0; i<64; i++) /* |u| = i */ + { + mpfr_random (x); + mpfr_set (y, x, GMP_RNDN); + set_bit (x, i + 1, 1); + set_bit (y, i + 1, 0); + for (j=0; j<64; j++) /* |v| = j */ + { + b = random () % 2; + set_bit (x, i + j + 2, b); + set_bit (y, i + j + 2, b); + + for (k=0; k<64; k++) + { + + if (k) set_bit (x, i + j + k + 1, 0); + if (k) set_bit (y, i + j + k + 1, 1); + + set_bit (x, i + j + k + 2, 1); + set_bit (y, i + j + k + 2, 0); + l = mpfr_cmp2 (x, y); + expected = i + j + k + 1; + if (l != expected) + { + fprintf (stderr, "Error in mpfr_cmp2:\nx="); + mpfr_out_str (stderr, 2, 0, x, GMP_RNDN); + fprintf (stderr, "\ny="); + mpfr_out_str (stderr, 2, 0, y, GMP_RNDN); + fprintf (stderr, "\ngot %u instead of %u\n", l, expected); + exit(1); + } + + set_bit (x, i + j + k + 2, 0); + set_bit (x, i + j + k + 3, 0); + set_bit (y, i + j + k + 3, 1); + l = mpfr_cmp2 (x, y); + expected = i + j + k + 2; + if (l != expected) + { + fprintf (stderr, "Error in mpfr_cmp2:\nx="); + mpfr_out_str (stderr, 2, 0, x, GMP_RNDN); + fprintf (stderr, "\ny="); + mpfr_out_str (stderr, 2, 0, y, GMP_RNDN); + fprintf (stderr, "\ngot %u instead of %u\n", l, expected); + exit(1); + } + } + } + } + + mpfr_clear (x); + mpfr_clear (y); +} + +void +tcmp2 (double x, double y, int i) { mpfr_t xx, yy; int j; @@ -40,11 +155,15 @@ void tcmp2 (double x, double y, int i) else i = (int) floor(log(x)/log(2.0)) - (int) floor(log(x-y)/log(2.0)); } mpfr_init2(xx, 53); mpfr_init2(yy, 53); - mpfr_set_d(xx, x, 0); - mpfr_set_d(yy, y, 0); - j = mpfr_cmp2(xx, yy); + mpfr_set_d (xx, x, GMP_RNDN); + mpfr_set_d (yy, y, GMP_RNDN); + j = mpfr_cmp2 (xx, yy); if (j != i) { - printf("Error in mpfr_cmp2: x=%1.20e y=%1.20e mpfr_cmp2(x,y)=%d instead of %d\n",x,y,j,i); + fprintf (stderr, "Error in mpfr_cmp2 for\nx="); + mpfr_out_str (stderr, 2, 0, xx, GMP_RNDN); + fprintf (stderr, "\ny="); + mpfr_out_str (stderr, 2, 0, yy, GMP_RNDN); + fprintf (stderr, "\ngot %u instead of %u\n", j, i); exit(1); } mpfr_clear(xx); mpfr_clear(yy); @@ -57,6 +176,23 @@ void special () mpfr_init (x); mpfr_init (y); + /* bug found by Nathalie Revol, 21 March 2001 */ + mpfr_set_prec (x, 65); + mpfr_set_prec (y, 65); + mpfr_set_str_raw (x, "0.10000000000000000000000000000000000001110010010110100110011110000E1"); + mpfr_set_str_raw (y, "0.11100100101101001100111011111111110001101001000011101001001010010E-35"); + if ((j = mpfr_cmp2 (x, y)) != 1) { + printf ("Error in mpfr_cmp2:\n"); + printf ("x="); + mpfr_print_raw (x); + putchar ('\n'); + printf ("y="); + mpfr_print_raw (y); + putchar ('\n'); + printf ("got %d, expected 1\n", j); + exit (1); + } + mpfr_set_prec(x, 127); mpfr_set_prec(y, 127); mpfr_set_str_raw(x, "0.1011010000110111111000000101011110110001000101101011011110010010011110010000101101000010011001100110010000000010110000101000101E6"); mpfr_set_str_raw(y, "0.1011010000110111111000000101011011111100011101000011001111000010100010100110110100110010011001100110010000110010010110000010110E6"); @@ -79,10 +215,47 @@ void special () exit(1); } + /* bug found by Nathalie Revol, 29 March 2001 */ + mpfr_set_prec (x, 130); mpfr_set_prec (y, 130); + mpfr_set_str_raw (x, "0.1100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E2"); + mpfr_set_str_raw (y, "0.1011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100E2"); + if ((j=mpfr_cmp2(x, y)) != 127) { + printf("Error in mpfr_cmp2:\n"); + printf("x="); mpfr_print_raw(x); putchar('\n'); + printf("y="); mpfr_print_raw(y); putchar('\n'); + printf("got %d, expected 127\n", j); + exit(1); + } + + /* bug found by Nathalie Revol, 2 Apr 2001 */ + mpfr_set_prec (x, 65); mpfr_set_prec (y, 65); + mpfr_set_ui (x, 5, GMP_RNDN); + mpfr_set_str_raw (y, "0.10011111111111111111111111111111111111111111111111111111111111101E3"); + if ((j=mpfr_cmp2(x, y)) != 63) { + printf("Error in mpfr_cmp2:\n"); + printf("x="); mpfr_print_raw(x); putchar('\n'); + printf("y="); mpfr_print_raw(y); putchar('\n'); + printf("got %d, expected 63\n", j); + exit(1); + } + + /* bug found by Nathalie Revol, 2 Apr 2001 */ + mpfr_set_prec (x, 65); mpfr_set_prec (y, 65); + mpfr_set_str_raw (x, "0.10011011111000101001110000000000000000000000000000000000000000000E-69"); + mpfr_set_str_raw (y, "0.10011011111000101001101111111111111111111111111111111111111111101E-69"); + if ((j=mpfr_cmp2(x, y)) != 63) { + printf("Error in mpfr_cmp2:\n"); + printf("x="); mpfr_print_raw(x); putchar('\n'); + printf("y="); mpfr_print_raw(y); putchar('\n'); + printf("got %d, expected 63\n", j); + exit(1); + } + mpfr_clear(x); mpfr_clear(y); } -int main() +int +main (void) { int i,j; double x=1.0, y, z; #ifdef __mips @@ -93,12 +266,17 @@ int main() set_fpc_csr(exp.fc_word); #endif + worst_cases (); special (); tcmp2(5.43885304644369510000e+185, -1.87427265794105340000e-57, 1); tcmp2(1.06022698059744327881e+71, 1.05824655795525779205e+71, -1); tcmp2(1.0, 1.0, 53); for (i=0;i<54;i++) { - tcmp2(1.0, 1.0-x, i); + tcmp2 (1.0, 1.0-x, i); + x /= 2.0; + } + for (x=0.5, i=1; i<100; i++) { + tcmp2 (1.0, x, 1); x /= 2.0; } for (j=0; j<100000; j++) { @@ -107,6 +285,6 @@ int main() if (x<y) { z=x; x=y; y=z; } if (y != 0.0 && y != -0.0) tcmp2(x, y, -1); } + return 0; } - diff --git a/mpfr/tests/tcmp_ui.c b/mpfr/tests/tcmp_ui.c index ce0eb2ca5..601bc3ab3 100644 --- a/mpfr/tests/tcmp_ui.c +++ b/mpfr/tests/tcmp_ui.c @@ -1,20 +1,20 @@ /* Test file for mpfr_cmp_ui. -Copyright (C) 1999 Free Software Foundation. +Copyright (C) 1999, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ @@ -25,7 +25,8 @@ MA 02111-1307, USA. */ #include "gmp.h" #include "mpfr.h" -int main() +int +main (void) { mpfr_t x; unsigned long i; long s; @@ -47,6 +48,13 @@ int main() mpfr_clear(x); exit(1); } + mpfr_set_ui (x, 0, GMP_RNDZ); + mpfr_neg (x, x, GMP_RNDZ); + if (mpfr_cmp_ui (x, i=0)) { + printf("Error in mpfr_cmp_ui(%1.20f,%lu)\n",mpfr_get_d(x), i); + mpfr_clear(x); + exit(1); + } mpfr_set_si(x, -3, GMP_RNDZ); if (mpfr_cmp_si(x, s=-3)!=0) { @@ -65,6 +73,15 @@ int main() exit(1); } + mpfr_set_ui (x, 0, GMP_RNDN); + mpfr_ui_div (x, 1, x, GMP_RNDU); + if (mpfr_cmp_ui (x, 0) == 0) + { + fprintf (stderr, "Error in mpfr_cmp_ui (Inf, 0)\n"); + exit (1); + } + mpfr_clear(x); + return 0; } diff --git a/mpfr/tests/tcos.c b/mpfr/tests/tcos.c new file mode 100644 index 000000000..5b5ff0692 --- /dev/null +++ b/mpfr/tests/tcos.c @@ -0,0 +1,121 @@ +/* Test file for mpfr_cos. + +Copyright (C) 2001 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 <stdio.h> +#include <stdlib.h> +#include <math.h> +#include "gmp.h" +#include "mpfr.h" + +void check53 _PROTO ((double, double, mp_rnd_t)); + +void check53 (double x, double cos_x, mp_rnd_t rnd_mode) +{ + mpfr_t xx, c; + + mpfr_init2 (xx, 53); + mpfr_init2 (c, 53); + mpfr_set_d (xx, x, rnd_mode); /* should be exact */ + mpfr_cos (c, xx, rnd_mode); + if (mpfr_get_d (c) != cos_x && (!isnan(cos_x) || !isnan(mpfr_get_d(c)))) + { + fprintf (stderr, "mpfr_cos failed for x=%1.20e, rnd=%s\n", x, + mpfr_print_rnd_mode (rnd_mode)); + fprintf (stderr, "mpfr_cos gives cos(x)=%1.20e, expected %1.20e\n", + mpfr_get_d (c), cos_x); + exit (1); + } + mpfr_clear (xx); + mpfr_clear (c); +} + +#define TEST_FUNCTION mpfr_cos +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y; + + mpfr_init (x); + mpfr_init (y); + + mpfr_set_prec (x, 30); + mpfr_set_prec (y, 30); + mpfr_set_str_raw (x, "1.00001010001101110010100010101e-1"); + mpfr_cos (y, x, GMP_RNDU); + mpfr_set_str_raw (x, "1.10111100010101011110101010100e-1"); + if (mpfr_cmp (y, x)) + { + fprintf (stderr, "Error for prec=30, rnd=GMP_RNDU\n"); + printf ("expected "); mpfr_print_raw (x); putchar ('\n'); + printf (" got "); mpfr_print_raw (y); putchar ('\n'); + exit (1); + } + + mpfr_set_prec (x, 59); + mpfr_set_prec (y, 59); + mpfr_set_str_raw (x, "1.01101011101111010011111110111111111011011101100111100011e-3"); + mpfr_cos (y, x, GMP_RNDU); + mpfr_set_str_raw (x, "1.1111011111110010001001001011100111101110100010000010010011e-1"); + if (mpfr_cmp (y, x)) + { + fprintf (stderr, "Error for prec=59, rnd=GMP_RNDU\n"); + printf ("expected "); mpfr_print_raw (x); putchar ('\n'); + printf (" got "); mpfr_print_raw (y); putchar ('\n'); + exit (1); + } + + mpfr_set_prec (x, 5); + mpfr_set_prec (y, 5); + mpfr_set_str_raw (x, "1.1100e-2"); + mpfr_cos (y, x, GMP_RNDD); + mpfr_set_str_raw (x, "1.1100e-1"); + if (mpfr_cmp (y, x)) + { + fprintf (stderr, "Error for x=1.1100e-2, rnd=GMP_RNDD\n"); + printf ("expected 1.1100e-1, got "); mpfr_print_raw (y); putchar ('\n'); + exit (1); + } + + check53(0.0/0.0, 0.0/0.0, GMP_RNDN); + check53(1.0/0.0, 0.0/0.0, GMP_RNDN); + check53(-1.0/0.0, 0.0/0.0, GMP_RNDN); + + /* worst case from PhD thesis of Vincent Lefe`vre: x=8980155785351021/2^54 */ + check53 (4.984987858808754279e-1, 8.783012931285841817e-1, GMP_RNDN); + check53 (4.984987858808754279e-1, 8.783012931285840707e-1, GMP_RNDD); + check53 (4.984987858808754279e-1, 8.783012931285840707e-1, GMP_RNDZ); + check53 (4.984987858808754279e-1, 8.783012931285841817e-1, GMP_RNDU); + check53 (1.00031274099908640274, 0.540039116973283217504, GMP_RNDN); + check53 (1.00229256850978698523, 0.538371757797526551137, GMP_RNDZ); + check53 (1.00288304857059840103, 0.537874062022526966409, GMP_RNDZ); + check53 (1.00591265847407274059, 0.53531755997839769456, GMP_RNDN); + + check53 (1.00591265847407274059, 0.53531755997839769456, GMP_RNDN); + + test_generic (1, 100, 100); + + mpfr_clear (x); + mpfr_clear (y); + + return 0; +} diff --git a/mpfr/tests/tcosh.c b/mpfr/tests/tcosh.c new file mode 100644 index 000000000..6792c1626 --- /dev/null +++ b/mpfr/tests/tcosh.c @@ -0,0 +1,37 @@ +/* Test file for mpfr_cosh. + +Copyright (C) 2001 Free Software Foundation. +Adapted from tarctan.c. + +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 <stdio.h> +#include <stdlib.h> +#include <gmp.h> +#include <mpfr.h> + +#define TEST_FUNCTION mpfr_cosh +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + test_generic (1, 100, 100); + + return 0; +} diff --git a/mpfr/tests/tdiv.c b/mpfr/tests/tdiv.c index b97e5d1b4..48a0a9d04 100644 --- a/mpfr/tests/tdiv.c +++ b/mpfr/tests/tdiv.c @@ -1,20 +1,20 @@ /* Test file for mpfr_div. -Copyright (C) 1999 Free Software Foundation. +Copyright (C) 1999, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ @@ -33,6 +33,8 @@ void check4 _PROTO((double, double, mp_rnd_t, int, double)); void check24 _PROTO((float, float, mp_rnd_t, float)); void check_float _PROTO((void)); void check_convergence _PROTO((void)); +void check_lowr _PROTO((void)); +void check_inexact _PROTO((void)); void check4 (double N, double D, mp_rnd_t rnd_mode, int p, double Q) { @@ -164,8 +166,222 @@ void check_convergence () mpfr_clear(x); mpfr_clear(y); } -int main(int argc, char *argv[]) +void check_lowr () { + mpfr_t x, y, z, z2, z3, tmp; + int k, c; + + + mpfr_init2 (x, 1000); + mpfr_init2 (y, 100); + mpfr_init2 (tmp, 850); + mpfr_init2 (z, 10); + mpfr_init2 (z2, 10); + mpfr_init2 (z3, 50); + + for (k = 1; k < 10000; k++) + { + mpfr_random (z); + mpfr_random (tmp); + mpfr_mul (x, z, tmp, GMP_RNDN); + c = mpfr_div (z2, x, tmp, GMP_RNDN); + + if (c || mpfr_cmp(z2, z)) + { + fprintf(stderr, "Error in mpfr_div rnd=GMP_RNDN\n"); + printf("Dividing "); + printf("got "); mpfr_print_raw(z2); putchar('\n'); + printf("instead of "); mpfr_print_raw(z); putchar('\n'); + printf("inex flag = %d\n", c); + exit(1); + } + } + + mpfr_set_prec(z2, 9); + for (k = 1; k < 10000; k++) + { + mpfr_random(z); + mpfr_random(tmp); + mpfr_mul(x, z, tmp, GMP_RNDN); + c = mpfr_div(z2, x, tmp, GMP_RNDN); + + if ((mpfr_cmp(z2, z) == 0 && c) || c == -1) + { + fprintf(stderr, "Error in mpfr_div rnd=GMP_RNDN\n"); + printf("Dividing "); + printf("got "); mpfr_print_raw(z2); putchar('\n'); + printf("instead of "); mpfr_print_raw(z); putchar('\n'); + printf("inex flag = %d\n", c); + exit(1); + } + else if (c == 2) + { + mpfr_add_one_ulp(z); + if (mpfr_cmp(z2, z)) + { + fprintf(stderr, "Error in mpfr_div [even rnd?] rnd=GMP_RNDN\n"); + printf("Dividing "); + printf("got "); mpfr_print_raw(z2); putchar('\n'); + printf("instead of "); mpfr_print_raw(z); putchar('\n'); + printf("inex flag = %d\n", 1); + exit(1); + } + } + else if (c == -2) + { + mpfr_sub_one_ulp(z); + if (mpfr_cmp(z2, z)) + { + fprintf(stderr, "Error in mpfr_div [even rnd?] rnd=GMP_RNDN\n"); + printf("Dividing "); + printf("got "); mpfr_print_raw(z2); putchar('\n'); + printf("instead of "); mpfr_print_raw(z); putchar('\n'); + printf("inex flag = %d\n", 1); + exit(1); + } + } + } + + + mpfr_set_prec(x, 1000); + mpfr_set_prec(y, 100); + mpfr_set_prec(tmp, 850); + mpfr_set_prec(z, 10); + mpfr_set_prec(z2, 10); + + /* almost exact divisions */ + for (k = 1; k < 10000; k++) + { + mpfr_random(z); + mpfr_random(tmp); + mpfr_mul(x, z, tmp, GMP_RNDN); + mpfr_set(y, tmp, GMP_RNDD); + mpfr_add_one_ulp(x); + + c = mpfr_div(z2, x, y, GMP_RNDD); + mpfr_div(z3, x, y, GMP_RNDD); + mpfr_set(z, z3, GMP_RNDD); + + if (c != -1 || mpfr_cmp(z2, z)) + { + fprintf(stderr, "Error in mpfr_div rnd=GMP_RNDD\n"); + printf("got "); mpfr_print_raw(z2); putchar('\n'); + printf("instead of "); mpfr_print_raw(z); putchar('\n'); + printf("inex flag = %d\n", c); + exit(1); + } + + mpfr_set(y, tmp, GMP_RNDU); + c = mpfr_div(z2, x, y, GMP_RNDU); + mpfr_div(z3, x, y, GMP_RNDU); + mpfr_set(z, z3, GMP_RNDU); + if (c != 1 || mpfr_cmp(z2, z)) + { + fprintf(stderr, "Error in mpfr_div rnd=GMP_RNDU\n"); + printf("got "); mpfr_print_raw(z2); putchar('\n'); + printf("instead of "); mpfr_print_raw(z); putchar('\n'); + printf("inex flag = %d\n", c); + exit(1); + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (z2); + mpfr_clear (z3); + mpfr_clear (tmp); +} + +#define MAX_PREC 100 + +void +check_inexact () +{ + mpfr_t x, y, z, u; + mp_prec_t px, py, pu; + int inexact, cmp; + mp_rnd_t rnd; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + mpfr_init (u); + + mpfr_set_prec (x, 33); + mpfr_set_str_raw (x, "0.101111100011011101010011101100001E0"); + mpfr_set_prec (u, 1); + mpfr_set_str_raw (u, "0.1E0"); + mpfr_set_prec (y, 28); + if ((inexact = mpfr_div (y, x, u, GMP_RNDN) >= 0)) + { + fprintf (stderr, "Wrong inexact flag (1): expected -1, got %d\n", + inexact); + exit (1); + } + + mpfr_set_prec (x, 129); + mpfr_set_str_raw (x, "0.111110101111001100000101011100101100110011011101010001000110110101100101000010000001110110100001101010001010100010001111001101010E-2"); + mpfr_set_prec (u, 15); + mpfr_set_str_raw (u, "0.101101000001100E-1"); + mpfr_set_prec (y, 92); + if ((inexact = mpfr_div (y, x, u, GMP_RNDN) <= 0)) + { + fprintf (stderr, "Wrong inexact flag (1): expected 1, got %d\n", + inexact); + mpfr_print_raw(y); putchar('\n'); + exit (1); + } + + for (px=1; px<MAX_PREC; px++) + { + mpfr_set_prec (x, px); + mpfr_random (x); + for (pu=1; pu<=MAX_PREC; pu++) + { + mpfr_set_prec (u, pu); + do { mpfr_random (u); } while (mpfr_cmp_ui (u, 0) == 0); + for (py=1; py<=MAX_PREC; py++) + { + mpfr_set_prec (y, py); + mpfr_set_prec (z, py + pu); + for (rnd=0; rnd<4; rnd++) + { + inexact = mpfr_div (y, x, u, rnd); + if (mpfr_mul (z, y, u, rnd)) + { + fprintf (stderr, "z <- y * u should be exact\n"); + exit (1); + } + cmp = mpfr_cmp (z, x); + if (((inexact == 0) && (cmp != 0)) || + ((inexact > 0) && (cmp <= 0)) || + ((inexact < 0) && (cmp >= 0))) + { + fprintf (stderr, "Wrong inexact flag for rnd=%s\n", + mpfr_print_rnd_mode(rnd)); + printf ("expected %d, got %d\n", cmp, inexact); + printf ("x="); mpfr_print_raw (x); putchar ('\n'); + printf ("u="); mpfr_print_raw (u); putchar ('\n'); + printf ("y="); mpfr_print_raw (y); putchar ('\n'); + printf ("y*u="); mpfr_print_raw (z); putchar ('\n'); + exit (1); + } + } + } + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (u); +} + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y, z; int N; #ifdef TEST @@ -180,6 +396,17 @@ int main(int argc, char *argv[]) #endif N = (argc>1) ? atoi(argv[1]) : 100000; + check_inexact(); + + mpfr_init2 (x, 64); + mpfr_init2 (y, 64); + mpfr_init2 (z, 64); + + mpfr_set_str_raw(x, "1.00100100110110101001010010101111000001011100100101010000000000E54"); + mpfr_set_str_raw(y, "1.00000000000000000000000000000000000000000000000000000000000000E584"); + mpfr_div(z, x, y, GMP_RNDU); + + check_lowr(); check_float(); /* checks single precision */ check_convergence(); check53(0.0, 1.0, GMP_RNDZ, 0.0); @@ -209,6 +436,7 @@ int main(int argc, char *argv[]) -4.0250194961676020848e-258); check53(1.04636807108079349236e-189, 3.72295730823253012954e-292, GMP_RNDZ, 2.810583051186143125e102); + #ifdef TEST srand48(getpid()); for (i=0;i<N;i++) { @@ -218,5 +446,10 @@ int main(int argc, char *argv[]) check4(n, d, rand() % 4, 53, 0.0); } #endif + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + return 0; } diff --git a/mpfr/tests/tdiv_ui.c b/mpfr/tests/tdiv_ui.c index df6294793..5fcc5639b 100644 --- a/mpfr/tests/tdiv_ui.c +++ b/mpfr/tests/tdiv_ui.c @@ -1,20 +1,20 @@ /* Test file for mpfr_div_ui. -Copyright (C) 1999 Free Software Foundation. +Copyright (C) 1999-2001 Free Software Foundation. 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ @@ -28,10 +28,13 @@ MA 02111-1307, USA. */ #include "mpfr-test.h" void check _PROTO((double, unsigned long, mp_rnd_t, double)); +void special _PROTO((void)); +void check_inexact _PROTO((void)); void check (double d, unsigned long u, mp_rnd_t rnd, double e) { - mpfr_t x, y; double f; + mpfr_t x, y; + double f; mpfr_init2(x, 53); mpfr_init2(y, 53); #ifdef TEST @@ -50,8 +53,119 @@ void check (double d, unsigned long u, mp_rnd_t rnd, double e) mpfr_clear(x); mpfr_clear(y); } +void +special (void) +{ + mpfr_t x, y; + unsigned xprec, yprec; + + mpfr_init (x); + mpfr_init (y); + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + mpfr_set_ui (x, 1, GMP_RNDN); + mpfr_div_ui (y, x, 3, GMP_RNDN); + + mpfr_set_prec (x, 100); + mpfr_set_prec (y, 100); + mpfr_random (x); + mpfr_div_ui (y, x, 123456, GMP_RNDN); + mpfr_set_ui (x, 0, GMP_RNDN); + mpfr_div_ui (y, x, 123456789, GMP_RNDN); + if (mpfr_cmp_ui (y, 0)) + { + fprintf (stderr, "mpfr_div_ui gives non-zero for 0/ui\n"); + exit (1); + } + + /* bug found by Norbert Mueller, 21 Aug 2001 */ + mpfr_set_prec (x, 110); + mpfr_set_prec (y, 60); + mpfr_set_str_raw (x, "0.110101110011111110011111001110011001110111000000111110001000111011000011E-44"); + mpfr_div_ui(y, x, 17, __gmp_default_rounding_mode); + if (mpfr_get_d (y) != 2.8114572543455207632e-15) + { + fprintf (stderr, "Error in x / 17 for x=1/16!\n"); + exit (1); + } + + for (xprec = 53; xprec <= 128; xprec++) + { + mpfr_set_prec (x, xprec); + mpfr_set_str_raw (x, "0.1100100100001111110011111000000011011100001100110111E2"); + for (yprec = 53; yprec <= 128; yprec++) + { + mpfr_set_prec (y, yprec); + mpfr_div_ui (y, x, 1, GMP_RNDN); + if (mpfr_get_d (x) != mpfr_get_d (y)) + { + fprintf (stderr, "division by 1.0 fails for xprec=%u, yprec=%u\n", xprec, yprec); + printf ("expected "); mpfr_print_raw (x); putchar ('\n'); + printf ("got "); mpfr_print_raw (y); putchar ('\n'); + exit (1); + } + } + } + + mpfr_clear (x); + mpfr_clear (y); +} + +void +check_inexact () +{ + mpfr_t x, y, z; + mp_prec_t px, py; + int inexact, cmp; + unsigned long int u; + mp_rnd_t rnd; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + + for (px=1; px<300; px++) + { + mpfr_set_prec (x, px); + mpfr_random (x); + do { u = lrand48 (); } while (u == 0); + for (py=1; py<300; py++) + { + mpfr_set_prec (y, py); + mpfr_set_prec (z, py + mp_bits_per_limb); + for (rnd=0; rnd<4; rnd++) + { + inexact = mpfr_div_ui (y, x, u, rnd); + if (mpfr_mul_ui (z, y, u, rnd)) + { + fprintf (stderr, "z <- y * u should be exact for u=%lu\n", u); + printf ("y="); mpfr_print_raw (y); putchar ('\n'); + printf ("z="); mpfr_print_raw (z); putchar ('\n'); + exit (1); + } + cmp = mpfr_cmp (z, x); + if (((inexact == 0) && (cmp != 0)) || + ((inexact > 0) && (cmp <= 0)) || + ((inexact < 0) && (cmp >= 0))) + { + fprintf (stderr, "Wrong inexact flag for u=%lu, rnd=%s\n", u, + mpfr_print_rnd_mode(rnd)); + printf ("x="); mpfr_print_raw (x); putchar ('\n'); + printf ("y="); mpfr_print_raw (y); putchar ('\n'); + exit (1); + } + } + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} + int -main(int argc, char **argv) +main (int argc, char **argv) { mpfr_t x; #ifdef TEST @@ -65,6 +179,10 @@ main(int argc, char **argv) } #endif + check_inexact (); + + special (); + check(1.0, 3, GMP_RNDN, 3.3333333333333331483e-1); check(1.0, 3, GMP_RNDZ, 3.3333333333333331483e-1); check(1.0, 3, GMP_RNDU, 3.3333333333333337034e-1); diff --git a/mpfr/tests/tdump.c b/mpfr/tests/tdump.c index 17b000496..8c3a51f09 100644 --- a/mpfr/tests/tdump.c +++ b/mpfr/tests/tdump.c @@ -1,30 +1,32 @@ /* Test file for mpfr_dump. -Copyright (C) 2000 Free Software Foundation. +Copyright (C) 2000, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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 <stdio.h> #include <stdlib.h> #include <unistd.h> #include "gmp.h" #include "mpfr.h" -int main() +int +main (void) { mpfr_t z; @@ -33,6 +35,6 @@ int main() mpfr_dump(z, GMP_RNDD); printf(" ^--- 0.e1 printed above is ok\n"); mpfr_clear(z); + return 0; } - diff --git a/mpfr/tests/teq.c b/mpfr/tests/teq.c index b5a3ff6f0..ded05aca8 100644 --- a/mpfr/tests/teq.c +++ b/mpfr/tests/teq.c @@ -1,20 +1,20 @@ /* Test file for mpfr_eq. -Copyright (C) 1999-2000 Free Software Foundation. +Copyright (C) 1999, 2000, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ @@ -60,7 +60,8 @@ void teq (mpfr_t x) mpfr_clear(y); } -int main() +int +main (void) { int j; mpfr_t x; @@ -71,6 +72,6 @@ int main() teq (x); } mpfr_clear (x); + return 0; } - diff --git a/mpfr/tests/teuler.c b/mpfr/tests/teuler.c new file mode 100644 index 000000000..c1a82e00d --- /dev/null +++ b/mpfr/tests/teuler.c @@ -0,0 +1,90 @@ +/* Test file for mpfr_const_euler. + +Copyright (C) 2001 Free Software Foundation. + +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 <stdio.h> +#include <stdlib.h> +#include "gmp.h" +#include "mpfr.h" +#include "mpfr-impl.h" + +int +main (int argc, char *argv[]) +{ + mpfr_t gamma, y, z, t; + unsigned int err, prec, yprec, p0 = 1, p1 = 200; + mp_rnd_t rnd; + + prec = (argc < 2) ? 53 : atoi(argv[1]); + + if (argc > 1) + { + mpfr_init2 (gamma, prec); + mpfr_const_euler (gamma, GMP_RNDN); + printf("gamma="); mpfr_out_str (stdout, 10, 0, gamma, GMP_RNDD); + putchar ('\n'); + mpfr_clear (gamma); + return 0; + } + + mpfr_init (y); + mpfr_init (z); + mpfr_init (t); + + for (prec = p0; prec <= p1; prec++) + { + mpfr_set_prec (z, prec); + mpfr_set_prec (t, prec); + yprec = prec + 10; + + for (rnd=0; rnd<4; rnd++) + { + mpfr_set_prec (y, yprec); + mpfr_const_euler (y, rnd); + err = (rnd == GMP_RNDN) ? yprec + 1 : yprec; + if (mpfr_can_round (y, err, rnd, rnd, prec)) + { + mpfr_set (t, y, rnd); + mpfr_const_euler (z, rnd); + if (mpfr_cmp (t, z)) + { + printf ("results differ for prec=%u rnd_mode=%s\n", prec, + mpfr_print_rnd_mode (rnd)); + printf (" got "); + mpfr_out_str (stdout, 2, prec, z, GMP_RNDN); + putchar ('\n'); + printf (" expected "); + mpfr_out_str (stdout, 2, prec, t, GMP_RNDN); + putchar ('\n'); + printf (" approximation was "); + mpfr_print_raw (y); + putchar ('\n'); + exit (1); + } + } + } + } + + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (t); + + return 0; +} diff --git a/mpfr/tests/texceptions.c b/mpfr/tests/texceptions.c new file mode 100644 index 000000000..6c2b1b7e2 --- /dev/null +++ b/mpfr/tests/texceptions.c @@ -0,0 +1,123 @@ +/* Test file for exceptions. + +Copyright (C) 2001 Free Software Foundation. + +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 <stdio.h> +#include <stdlib.h> +#include <gmp.h> +#include <mpfr.h> + +void mpfr_set_double_range _PROTO((void)); + +void +mpfr_set_double_range (void) +{ + mpfr_set_default_prec (53); + + /* in double precision format, the unbiased exponent is between 0 and + 2047, where 0 is used for subnormal numbers, and 2047 for special + numbers (infinities, NaN), and the bias is 1023, thus "normal" numbers + have an exponent between -1022 and 1023, corresponding to numbers + between 2^(-1022) and previous(2^(1024)). + (The smallest subnormal number is 0.(0^51)1*2^(-1022)= 2^(-1074).) + + The smallest normal power of two is 1.0*2^(-1022). + The largest normal power of two is 2^1023. + (We have to add one for mpfr since mantissa are between 1/2 and 1.) + */ + + mpfr_set_emin (-1021); + mpfr_set_emax (1024); +} + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y; + mp_exp_t emin, emax; + + mpfr_init (x); + mpfr_init (y); + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + if (emin >= emax) + { + fprintf (stderr, "Error: emin >= emax\n"); + exit (1); + } + + mpfr_set_ui (x, 1, GMP_RNDN); + mpfr_mul_2exp (x, x, 1024, GMP_RNDN); + mpfr_set_double_range (); + mpfr_check_range (x, GMP_RNDN); + if (!mpfr_inf_p (x) || (mpfr_sgn(x) <= 0)) + { + fprintf (stderr, "Error: 2^1024 rounded to nearest should give +Inf\n"); + exit (1); + } + + mpfr_set_emax (1025); + mpfr_set_ui (x, 1, GMP_RNDN); + mpfr_mul_2exp (x, x, 1024, GMP_RNDN); + mpfr_set_double_range (); + mpfr_check_range (x, GMP_RNDD); + if (!mpfr_number_p (x)) + { + fprintf (stderr, "Error: 2^1024 rounded down should give a normal number\n"); + exit (1); + } + + mpfr_set_ui (x, 1, GMP_RNDN); + mpfr_mul_2exp (x, x, 1023, GMP_RNDN); + mpfr_add (x, x, x, GMP_RNDN); + if (!mpfr_inf_p (x) || (mpfr_sgn(x) <= 0)) + { + fprintf (stderr, "Error: x+x rounded to nearest for x=2^1023 should give +Inf\n"); + printf ("emax = %ld\n", mpfr_get_emax ()); + printf ("got "); mpfr_print_raw (x); putchar ('\n'); + exit (1); + } + + mpfr_set_ui (x, 1, GMP_RNDN); + mpfr_mul_2exp (x, x, 1023, GMP_RNDN); + mpfr_add (x, x, x, GMP_RNDD); + if (!mpfr_number_p (x)) + { + fprintf (stderr, "Error: x+x rounded down for x=2^1023 should give a normal number\n"); + exit (1); + } + + mpfr_set_ui (x, 1, GMP_RNDN); + mpfr_div_2exp (x, x, 1022, GMP_RNDN); + mpfr_set_str_raw (y, "1.1e-1022"); /* y = 3/2*x */ + mpfr_sub (y, y, x, GMP_RNDZ); + if (mpfr_cmp_ui (y, 0)) + { + fprintf (stderr, "Error: y-x rounded to zero should give 0 for y=3/2*2^(-1022), x=2^(-1022)\n"); + printf ("y="); mpfr_print_raw (y); putchar ('\n'); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + + return 0; +} diff --git a/mpfr/tests/texp.c b/mpfr/tests/texp.c index a441c2ea7..c613ab836 100644 --- a/mpfr/tests/texp.c +++ b/mpfr/tests/texp.c @@ -1,25 +1,26 @@ /* Test file for mpfr_exp. -Copyright (C) 1999 Free Software Foundation. +Copyright (C) 1999, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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 <math.h> +#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include "gmp.h" @@ -31,6 +32,8 @@ int check_large _PROTO((double, int, mp_rnd_t)); int check_worst_case _PROTO((double, double)); int check_worst_cases _PROTO((void)); void compare_exp2_exp3 _PROTO((int)); +extern int mpfr_exp_2 _PROTO((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); +extern int mpfr_exp3 _PROTO((mpfr_ptr, mpfr_srcptr, mp_rnd_t)); int maxu=0; @@ -154,10 +157,10 @@ int check_worst_cases () mpfr_set_prec (x, 601); mpfr_set_str_raw (x, "0.1000100010110110101110100101000100001110000100000100010100001110110111000010010110000111010010001011110010011101111111011101010001100110111100100001101101000111111011010010011001001100110111110010010010101010100011110110010010101111000111110011111110101101100111101100001000110000000111010100001111000000011101000011111101010011010010110101101010100010000000001001000111111111011011010011010100101101111101000101100011101111000110111010010100011001100000010001111011110110111101011011000100011000010100110101001101001111110110001111101000110010011101100100101000001010011011010010110100001101110100100E0"); mpfr_init2 (y, 601); - mpfr_exp2 (y, x, GMP_RNDD); + mpfr_exp_2 (y, x, GMP_RNDD); mpfr_exp3 (x, x, GMP_RNDD); if (mpfr_cmp (x, y)) { - fprintf (stderr, "mpfr_exp2 and mpfr_exp3 for prec=601\n"); + fprintf (stderr, "mpfr_exp_2 and mpfr_exp3 for prec=601\n"); exit (1); } @@ -175,13 +178,13 @@ void compare_exp2_exp3 (int n) mpfr_set_prec(x, prec); mpfr_set_prec(y, prec); mpfr_set_prec(z, prec); mpfr_random(x); rnd = rand() % 4; - mpfr_exp2 (y, x, rnd); + mpfr_exp_2 (y, x, rnd); mpfr_exp3 (z, x, rnd); if (mpfr_cmp(y,z)) { - printf("mpfr_exp2 and mpfr_exp3 disagree for rnd=%s and\nx=", + printf("mpfr_exp_2 and mpfr_exp3 disagree for rnd=%s and\nx=", mpfr_print_rnd_mode(rnd)); mpfr_print_raw(x); putchar('\n'); - printf("mpfr_exp2 gives "); mpfr_print_raw(y); putchar('\n'); + printf("mpfr_exp_2 gives "); mpfr_print_raw(y); putchar('\n'); printf("mpfr_exp3 gives "); mpfr_print_raw(z); putchar('\n'); exit(1); } @@ -189,17 +192,26 @@ void compare_exp2_exp3 (int n) mpfr_clear(x); mpfr_clear(y); mpfr_clear(z); } +#define TEST_FUNCTION mpfr_exp +#include "tgeneric.c" + int -main(int argc, char **argv) +main (int argc, char *argv[]) { #ifdef TEST int i, N, s=0, e, maxe=0; double d, lo, hi; #endif + test_generic (1, 100, 100); + + if (argc == 4) + { + check_large (atof(argv[1]), atoi(argv[2]), atoi(argv[3])); + exit(1); + } + srand(getpid()); - compare_exp2_exp3(1000); - if (argc==4) { check_large(atof(argv[1]), atoi(argv[2]), atoi(argv[3])); - exit(1); } + compare_exp2_exp3(500); check_worst_cases(); check3(0.0, GMP_RNDU, 1.0); check3(-8.88024741073346941839e-17, GMP_RNDU, 1.0); @@ -256,5 +268,6 @@ main(int argc, char **argv) } if (N) printf("mean error=%1.2e max error=%d\n", (double)s/(double)N,maxe); #endif + return 0; } diff --git a/mpfr/tests/texp2.c b/mpfr/tests/texp2.c new file mode 100644 index 000000000..bc02c0124 --- /dev/null +++ b/mpfr/tests/texp2.c @@ -0,0 +1,72 @@ +/* Test file for mpfr_exp2. + +Copyright (C) 2001 Free Software Foundation. +Adapted from tarctan.c. + +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 <stdio.h> +#include <stdlib.h> +#include <gmp.h> +#include "gmp-impl.h" +#include <mpfr.h> +#include "mpfr-impl.h" + +#define TEST_FUNCTION mpfr_exp2 +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y; + + mpfr_init (x); + mpfr_init (y); + + + MPFR_SET_INF(x); + mpfr_exp2 (y, x, GMP_RNDN); + if(!MPFR_IS_INF(y)) + { + printf ("evaluation of function in INF does not return INF"); + exit (1); + } + + MPFR_CHANGE_SIGN(x); + mpfr_exp2 (y, x, GMP_RNDN); + if(!MPFR_IS_ZERO(y)) + { + printf ("evaluation of function in -INF does not return 0"); + exit (1); + } + + MPFR_SET_NAN(x); + mpfr_exp2 (y, x, GMP_RNDN); + if(!MPFR_IS_NAN(y)) + { + printf ("evaluation of function in NAN does not return NAN"); + exit (1); + } + + test_generic (1, 100, 100); + + mpfr_clear (x); + mpfr_clear (y); + + return 0; +} diff --git a/mpfr/tests/texpm1.c b/mpfr/tests/texpm1.c new file mode 100644 index 000000000..14e53b773 --- /dev/null +++ b/mpfr/tests/texpm1.c @@ -0,0 +1,37 @@ +/* Test file for mpfr_expm1. + +Copyright (C) 2001 Free Software Foundation. +Adapted from tsinh.c. + +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 <stdio.h> +#include <stdlib.h> +#include <gmp.h> +#include <mpfr.h> + +#define TEST_FUNCTION mpfr_expm1 +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + test_generic (1, 100, 100); + + return 0; +} diff --git a/mpfr/tests/tfactorial.c b/mpfr/tests/tfactorial.c new file mode 100644 index 000000000..9656f4643 --- /dev/null +++ b/mpfr/tests/tfactorial.c @@ -0,0 +1,118 @@ +/* Test file for mpfr_factorial. + +Copyright (C) 2001 Free Software Foundation. +Adapted from tarctan.c. + +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 <stdio.h> +#include <stdlib.h> +#include "gmp.h" +#include "gmp-impl.h" +#include "mpfr.h" +#include "mpfr-impl.h" + +#define TEST_FUNCTION mpfr_fac_ui + +int +main (int argc, char *argv[]) +{ + unsigned int prec, err, yprec, n, k, zeros; + mp_rnd_t rnd; + mpfr_t x, y, z, t; + int inexact; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + mpfr_init (t); + + mpfr_fac_ui (y, 0, GMP_RNDN); + + if (mpfr_cmp_ui (y, 1)) + { + printf ("mpfr_fac_ui(0) does not give 1\n"); + exit (1); + } + + for (prec = 1; prec <= 100; prec++) + { + mpfr_set_prec (x, prec); + mpfr_set_prec (z, prec); + mpfr_set_prec (t, prec); + yprec = prec + 10; + mpfr_set_prec (y, yprec); + + for (n=0; n<100; n++) + for (rnd=0; rnd<4; rnd++) + { + inexact = mpfr_fac_ui (y, n, rnd); + err = (rnd == GMP_RNDN) ? yprec + 1 : yprec; + if (mpfr_can_round (y, err, rnd, rnd, prec)) + { + mpfr_set (t, y, rnd); + inexact = mpfr_fac_ui (z, n, rnd); + /* fact(n) ends with floor(n/2)+floor(n/4)+... zeros */ + for (k=n/2, zeros=0; k; k >>= 1) + zeros += k; + if (MPFR_EXP(y) <= prec + zeros) /* result should be exact */ + { + if (inexact) + { + fprintf (stderr, "Wrong inexact flag: expected exact\n"); + exit (1); + } + } + else /* result is inexact */ + { + if (!inexact) + { + fprintf (stderr, "Wrong inexact flag: expected inexact\n"); + printf ("n=%u prec=%u\n", n, prec); + mpfr_print_raw(z); putchar('\n'); + exit (1); + } + } + if (mpfr_cmp (t, z)) + { + printf ("results differ for x="); + mpfr_out_str (stdout, 2, prec, x, GMP_RNDN); + printf (" prec=%u rnd_mode=%s\n", prec, + mpfr_print_rnd_mode (rnd)); + printf (" got "); + mpfr_out_str (stdout, 2, prec, z, GMP_RNDN); + putchar ('\n'); + printf (" expected "); + mpfr_out_str (stdout, 2, prec, t, GMP_RNDN); + putchar ('\n'); + printf (" approximation was "); + mpfr_print_raw (y); + putchar ('\n'); + exit (1); + } + } + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (t); + + return 0; +} diff --git a/mpfr/tests/tfma.c b/mpfr/tests/tfma.c new file mode 100644 index 000000000..540203422 --- /dev/null +++ b/mpfr/tests/tfma.c @@ -0,0 +1,302 @@ +/* Test file for mpfr_fma. + +Copyright (C) 2001 Free Software Foundation. +Adapted from tarctan.c. + +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 <stdio.h> +#include <limits.h> +#include <stdlib.h> +#include <gmp.h> +#include "gmp-impl.h" +#include <mpfr.h> +#include "mpfr-impl.h" + + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y,z,s; + mpfr_init (x); + mpfr_init (s); + mpfr_init (y); + mpfr_init (z); + + + MPFR_SET_NAN(x); + mpfr_random(y); + mpfr_random(z); + mpfr_fma (s,x, y,z, GMP_RNDN); + if(!MPFR_IS_NAN(s)) + { + printf ("evaluation of function in x=NAN does not return NAN"); + exit (1); + } + + MPFR_CLEAR_FLAGS(x); + MPFR_CLEAR_FLAGS(y); + MPFR_CLEAR_FLAGS(z); + + MPFR_SET_NAN(y); + mpfr_random(x); + mpfr_random(z); + mpfr_fma (s,x, y,z, GMP_RNDN); + if(!MPFR_IS_NAN(s)) + { + printf ("evaluation of function in y=NAN does not return NAN"); + exit (1); + } + + MPFR_CLEAR_FLAGS(x); + MPFR_CLEAR_FLAGS(y); + MPFR_CLEAR_FLAGS(z); + + MPFR_SET_NAN(z); + mpfr_random(y); + mpfr_random(x); + mpfr_fma (s,x, y,z, GMP_RNDN); + if(!MPFR_IS_NAN(s)) + { + printf ("evaluation of function in z=NAN does not return NAN"); + exit (1); + } + + MPFR_CLEAR_FLAGS(x); + MPFR_CLEAR_FLAGS(y); + MPFR_CLEAR_FLAGS(z); + + MPFR_SET_INF(x); + MPFR_SET_ZERO(y); + mpfr_random(z); + mpfr_fma (s,x, y,z, GMP_RNDN); + if(!MPFR_IS_NAN(s)) + { + printf ("evaluation of function in x=INF y=0 does not return NAN"); + exit (1); + } + + MPFR_CLEAR_FLAGS(z); + MPFR_CLEAR_FLAGS(y); + MPFR_CLEAR_FLAGS(x); + + MPFR_SET_INF(y); + MPFR_SET_ZERO(x); + mpfr_random(z); + mpfr_fma (s,x, y,z, GMP_RNDN); + if(!MPFR_IS_NAN(s)) + { + printf ("evaluation of function in x=0 y=INF does not return NAN"); + exit (1); + } + + MPFR_CLEAR_FLAGS(z); + MPFR_CLEAR_FLAGS(y); + MPFR_CLEAR_FLAGS(x); + + MPFR_SET_INF(x); + mpfr_random(y); + MPFR_SET_INF(z); + if((MPFR_SIGN(x) * MPFR_SIGN(y)) == MPFR_SIGN(z)) + MPFR_CHANGE_SIGN(z); + mpfr_fma (s,x, y,z, GMP_RNDN); + if(!MPFR_IS_NAN(s)) + { + printf ("evaluation of function in x=INF z=(-sign(x)*sign(y))INF does not return NAN"); + exit (1); + } + + MPFR_CLEAR_FLAGS(z); + MPFR_CLEAR_FLAGS(y); + MPFR_CLEAR_FLAGS(x); + + MPFR_SET_INF(y); + mpfr_random(x); + MPFR_SET_INF(z); + if((MPFR_SIGN(x) * MPFR_SIGN(y)) == MPFR_SIGN(z)) + MPFR_CHANGE_SIGN(z); + + mpfr_fma (s,x, y,z, GMP_RNDN); + if(!MPFR_IS_NAN(s)) + { + printf ("evaluation of function in y=INF z=(-sign(x)*sign(y))INF does not return NAN"); + exit (1); + } + + MPFR_CLEAR_FLAGS(z); + MPFR_CLEAR_FLAGS(y); + MPFR_CLEAR_FLAGS(x); + + MPFR_SET_INF(x); + mpfr_random(y); + mpfr_random(z); + mpfr_fma (s,x, y,z, GMP_RNDN); + if(!MPFR_IS_INF(s)) + { + printf ("evaluation of function in x=INF does not return INF"); + exit (1); + } + + MPFR_CLEAR_FLAGS(z); + MPFR_CLEAR_FLAGS(y); + MPFR_CLEAR_FLAGS(x); + + MPFR_SET_INF(y); + mpfr_random(x); + mpfr_random(z); + mpfr_fma (s,x, y,z, GMP_RNDN); + if(!MPFR_IS_INF(s)) + { + printf ("evaluation of function in y=INF does not return INF"); + exit (1); + } + + MPFR_CLEAR_FLAGS(z); + MPFR_CLEAR_FLAGS(y); + MPFR_CLEAR_FLAGS(x); + + MPFR_SET_INF(z); + mpfr_random(x); + mpfr_random(y); + mpfr_fma (s,x, y,z, GMP_RNDN); + if(!MPFR_IS_INF(s)) + { + printf ("evaluation of function in z=INF does not return INF"); + exit (1); + } + + MPFR_CLEAR_FLAGS(z); + MPFR_CLEAR_FLAGS(y); + MPFR_CLEAR_FLAGS(x); + + MPFR_SET_ZERO(x); + mpfr_random(y); + mpfr_random(z); + mpfr_fma (s,x, y,z, GMP_RNDN); + if(mpfr_cmp(s,z)!=0) + { + printf ("evaluation of function in x=0 does not return z\n"); + exit (1); + } + + MPFR_CLEAR_FLAGS(z); + MPFR_CLEAR_FLAGS(y); + MPFR_CLEAR_FLAGS(x); + + MPFR_SET_ZERO(y); + mpfr_random(x); + mpfr_random(z); + mpfr_fma (s,x, y,z, GMP_RNDN); + if(mpfr_cmp(s,z)!=0) + { + printf ("evaluation of function in y=0 does not return z\n"); + exit (1); + } + + MPFR_CLEAR_FLAGS(z); + MPFR_CLEAR_FLAGS(y); + MPFR_CLEAR_FLAGS(x); + + { + mp_prec_t prec; + mpfr_t t, slong; + mp_rnd_t rnd; + int inexact, compare; + unsigned int n; + + int p0=1; + int p1=200; + int N=200; + + mpfr_init (t); + mpfr_init (slong); + + /* generic test */ + for (prec = p0; prec <= p1; prec++) + { + mpfr_set_prec (x, prec); + mpfr_set_prec (y, prec); + mpfr_set_prec (z, prec); + mpfr_set_prec (s, prec); + mpfr_set_prec (t, prec); + + for (n=0; n<N; n++) + { + + mpfr_random (x); + mpfr_random (y); + mpfr_random (z); + + if (random() % 2) + mpfr_neg (x, x, GMP_RNDN); + if (random() % 2) + mpfr_neg (y, y, GMP_RNDN); + if (random() % 2) + mpfr_neg (z, z, GMP_RNDN); + + rnd = random () % 4; + mpfr_set_prec (slong, 2 * prec); + if (mpfr_mul (slong, x, y, rnd)) + { + fprintf (stderr, "x*y should be exact\n"); + exit (1); + } + compare = mpfr_add (t, slong, z, rnd); + inexact = mpfr_fma (s, x, y, z, rnd); + if (mpfr_cmp (s, t)) + { + printf ("results differ for x="); + mpfr_out_str (stdout, 2, prec, x, GMP_RNDN); + printf (" y="); + mpfr_out_str (stdout, 2, prec, y, GMP_RNDN); + printf (" z="); + mpfr_out_str (stdout, 2, prec, z, GMP_RNDN); + printf (" prec=%u rnd_mode=%s\n", (unsigned) prec, + mpfr_print_rnd_mode (rnd)); + printf ("got "); + mpfr_out_str (stdout, 2, prec, s, GMP_RNDN); + putchar ('\n'); + printf ("expected "); + mpfr_out_str (stdout, 2, prec, t, GMP_RNDN); + putchar ('\n'); + printf ("approx "); + mpfr_print_raw (slong); + putchar ('\n'); + exit (1); + } + if (((inexact == 0) && (compare != 0)) || + ((inexact < 0) && (compare >= 0)) || + ((inexact > 0) && (compare <= 0))) + { + fprintf (stderr, "Wrong inexact flag for rnd=%s: expected %d, got %d\n", + mpfr_print_rnd_mode (rnd), compare, inexact); + exit (1); + } + } + } + mpfr_clear (t); + mpfr_clear (slong); + + } + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (s); + + return 0; +} diff --git a/mpfr/tests/tgeneric.c b/mpfr/tests/tgeneric.c new file mode 100644 index 000000000..d03e3ed9e --- /dev/null +++ b/mpfr/tests/tgeneric.c @@ -0,0 +1,103 @@ +/* Generic test file for functions with one mpfr_t argument. + +Copyright (C) 2001 Free Software Foundation. + +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. */ + +void test_generic _PROTO((int, int, int)); + +void +test_generic (int p0, int p1, int N) +{ + mp_prec_t prec, yprec; + mpfr_t x, y, z, t; + mp_rnd_t rnd; + int inexact, compare, compare2; + unsigned int n; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + mpfr_init (t); + + /* generic test */ + for (prec = p0; prec <= p1; prec++) + { + mpfr_set_prec (x, prec); + mpfr_set_prec (z, prec); + mpfr_set_prec (t, prec); + yprec = prec + 10; + + for (n=0; n<N; n++) + { +#if defined(RAND_FUNCTION) + RAND_FUNCTION (x); +#else + mpfr_random (x); +#endif + rnd = random () % 4; + mpfr_set_prec (y, yprec); + compare = TEST_FUNCTION (y, x, rnd); + if (mpfr_can_round (y, yprec, rnd, rnd, prec)) + { + mpfr_set (t, y, rnd); + inexact = TEST_FUNCTION (z, x, rnd); + if (mpfr_cmp (t, z)) + { + printf ("results differ for x="); + mpfr_out_str (stdout, 2, prec, x, GMP_RNDN); + printf (" prec=%u rnd_mode=%s\n", (unsigned) prec, + mpfr_print_rnd_mode (rnd)); + printf ("got "); + mpfr_out_str (stdout, 2, prec, z, GMP_RNDN); + putchar ('\n'); + printf ("expected "); + mpfr_out_str (stdout, 2, prec, t, GMP_RNDN); + putchar ('\n'); + printf ("approx "); + mpfr_print_raw (y); + putchar ('\n'); + exit (1); + } + compare2 = mpfr_cmp (t, y); + /* if rounding to nearest, cannot know the sign of t - f(x) + because of composed rounding: y = o(f(x)) and t = o(y) */ + if ((rnd != GMP_RNDN) && (compare * compare2 >= 0)) + compare = compare + compare2; + else + compare = inexact; /* cannot determine sign(t-f(x)) */ + if (((inexact == 0) && (compare != 0)) || + ((inexact > 0) && (compare <= 0)) || + ((inexact < 0) && (compare >= 0))) + { + fprintf (stderr, "Wrong inexact flag for rnd=%s: expected %d, got %d\n", + mpfr_print_rnd_mode (rnd), compare, inexact); + printf ("x="); mpfr_print_raw (x); putchar ('\n'); + printf ("y="); mpfr_print_raw (y); putchar ('\n'); + printf ("t="); mpfr_print_raw (t); putchar ('\n'); + exit (1); + } + } + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (t); +} diff --git a/mpfr/tests/tget_d.c b/mpfr/tests/tget_d.c new file mode 100644 index 000000000..6a6bca608 --- /dev/null +++ b/mpfr/tests/tget_d.c @@ -0,0 +1,55 @@ +/* Test file for mpfr_get_d + +Copyright (C) 1999-2001 Free Software Foundation. + +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 <stdio.h> +#include <stdlib.h> +#include "gmp.h" +#include "mpfr.h" + +int +main (void) +{ + mpfr_t x; + + mpfr_init2 (x, 2); + + /* checks that rounds to nearest sets the last + bit to zero in case of equal distance */ + mpfr_set_d (x, 5.0, GMP_RNDN); + if (mpfr_get_d (x) != 4.0) + { + fprintf (stderr, "Error in tget_d: got %1.1f instead of 4.0\n", + mpfr_get_d (x)); + exit (1); + } + + mpfr_set_d (x, 9.84891017624509146344e-01, GMP_RNDU); + if (mpfr_get_d (x) != 1.0) + { + fprintf (stderr, "Error in tround: got %f instead of 1.0\n", + mpfr_get_d (x)); + exit (1); + } + + mpfr_clear(x); + + return 0; +} diff --git a/mpfr/tests/tget_str.c b/mpfr/tests/tget_str.c index b2b505b57..e27852350 100644 --- a/mpfr/tests/tget_str.c +++ b/mpfr/tests/tget_str.c @@ -1,20 +1,20 @@ /* Test file for mpfr_get_str. -Copyright (C) 1999 Free Software Foundation. +Copyright (C) 1999, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ @@ -62,7 +62,9 @@ void check3 (double d, mp_rnd_t rnd, char *res) void check_small () { - mpfr_t x; char *s, *t; mp_exp_t e; + mpfr_t x; + char *s; + mp_exp_t e; mpfr_init(x); @@ -75,19 +77,29 @@ void check_small () /* bug found by Johan Vervloet */ mpfr_set_prec(x, 6); mpfr_set_d(x, 688.0, GMP_RNDN); - t = mpfr_get_str(NULL, &e, 2, 4, x, GMP_RNDU); - if (strcmp(t, "1011") || (e!=10)) { + s = mpfr_get_str(NULL, &e, 2, 4, x, GMP_RNDU); + if (strcmp(s, "1011") || (e!=10)) { fprintf(stderr, "Error in mpfr_get_str: 688 printed up to 4 bits should give 1.011e9\ninstead of "); mpfr_out_str(stderr, 2, 4, x, GMP_RNDU); putchar('\n'); exit(1); } - free(t); + free(s); + + mpfr_set_prec (x, 38); + mpfr_set_str_raw (x, "1.0001110111110100011010100010010100110e-6"); + s = mpfr_get_str (NULL, &e, 8, 10, x, GMP_RNDU); + if (strcmp (s, "1073721522") || (e != -1)) + { + fprintf (stderr, "Error in mpfr_get_str (3): s=%s e=%d\n", s, (int) e); + exit (1); + } + free (s); mpfr_clear(x); } int -main(int argc, char **argv) +main (int argc, char *argv[]) { #ifdef TEST int i; double d; @@ -107,5 +119,6 @@ main(int argc, char **argv) check3(2.14478198760196000000e+16, GMP_RNDN, "21448"); check3(7.02293374921793516813e-84, GMP_RNDN, "70229"); check3(-6.7274500420134077e-87, GMP_RNDN, "-67275"); + return 0; } diff --git a/mpfr/tests/thyperbolic.c b/mpfr/tests/thyperbolic.c new file mode 100644 index 000000000..91b8b83f6 --- /dev/null +++ b/mpfr/tests/thyperbolic.c @@ -0,0 +1,597 @@ +/* Test file for hyperbolic function : mpfr_cosh, mpfr_sinh, mpfr_tanh, mpfr_acosh, mpfr_asinh, mpfr_atanh. + +Copyright (C) 2001 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 youroption) 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 MERCHANTABILITYor 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 <stdio.h> +#include <gmp.h> +#include <gmp-impl.h> +#include <mpfr.h> +#include <mpfr-impl.h> + + +int check_O _PROTO((void)); +int check_NAN _PROTO((void)); +int check_zero _PROTO((void)); +int check_INF _PROTO((void)); + + + +int check_NAN(void){ + + mpfr_t t, ch,sh,th,ach,ash,ath; + int tester; + + mpfr_init2(t,200); + mpfr_init2(ch,200); + mpfr_init2(sh,200); + mpfr_init2(th,200); + mpfr_init2(ach,200); + mpfr_init2(ash,200); + mpfr_init2(ath,200); + + MPFR_SET_NAN(t); + + /******cosh********/ + + tester=mpfr_cosh(ch,t,GMP_RNDD); + if (!MPFR_IS_NAN(ch) || !tester ) + { + printf("cosh NAN \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + /******sinh********/ + + tester=mpfr_sinh(sh,t,GMP_RNDD); + if (!MPFR_IS_NAN(sh) || !tester ) + { + printf("sinh NAN \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + /******tanh********/ + + tester=mpfr_tanh(th,t,GMP_RNDD); + if (!MPFR_IS_NAN(th) || !tester ) + { + printf("tanh NAN \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + /******acosh********/ + + tester=mpfr_acosh(ach,t,GMP_RNDD); + if (!MPFR_IS_NAN(ach) || !tester ) + { + printf("acosh NAN \n"); + return(1); + } + + /******asinh********/ + + tester=mpfr_asinh(ash,t,GMP_RNDD); + if (!MPFR_IS_NAN(ash) || !tester ) + { + printf("asinh NAN \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + /******atanh********/ + + tester=mpfr_atanh(ath,t,GMP_RNDD); + if (!MPFR_IS_NAN(ath) || !tester ) + { + printf("atanh NAN \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + + return(0); + +} +int check_zero(void){ + + mpfr_t t, ch,sh,th,ach,ash,ath; + int tester; + + mpfr_init2(t,200); + mpfr_init2(ch,200); + mpfr_init2(sh,200); + mpfr_init2(th,200); + mpfr_init2(ach,200); + mpfr_init2(ash,200); + mpfr_init2(ath,200); + + + mpfr_set_ui(t,0,GMP_RNDD); + + /******cosh********/ + + tester=mpfr_cosh(ch,t,GMP_RNDD); + if (!mpfr_cmp_ui(ch,1) || !tester ) + { + printf("cosh(0) \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + /******sinh********/ + + tester=mpfr_sinh(sh,t,GMP_RNDD); + if (!MPFR_IS_ZERO(sh) || !tester ) + { + printf("sinh(0) \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + /******tanh********/ + + tester=mpfr_tanh(th,t,GMP_RNDD); + if (!MPFR_IS_ZERO(th) || !tester ) + { + printf("tanh(0) \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + /******acosh********/ + + tester=mpfr_acosh(ach,t,GMP_RNDD); + if (!MPFR_IS_NAN(ach) || tester != -1 ) + { + printf("acosh(0) \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + /******asinh********/ + + tester=mpfr_asinh(ash,t,GMP_RNDD); + if (!MPFR_IS_ZERO(ash) || !tester ) + { + printf("asinh(0) \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + /******atanh********/ + + tester=mpfr_atanh(ath,t,GMP_RNDD); + if (!MPFR_IS_ZERO(ath) || !tester ) + { + printf("atanh(0) \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + + return(0); + +} + +int check_INF(void){ + + mpfr_t t, ch,sh,th,ach,ash,ath; + int tester; + + + mpfr_init2(t,200); + mpfr_init2(ch,200); + mpfr_init2(sh,200); + mpfr_init2(th,200); + mpfr_init2(ach,200); + mpfr_init2(ash,200); + mpfr_init2(ath,200); + + + MPFR_SET_INF(t); + + if(MPFR_SIGN(t)<0) + MPFR_CHANGE_SIGN(t); + + /******cosh********/ + + tester = mpfr_cosh(ch,t,GMP_RNDD); + if (!MPFR_IS_INF(ch) || MPFR_SIGN(ch) < 0 || tester ) + { + printf("cosh(INF) \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + /******sinh********/ + + tester=mpfr_sinh(sh,t,GMP_RNDD); + if (!MPFR_IS_INF(sh) || MPFR_SIGN(sh) < 0 || tester ) + { + printf("sinh(INF) \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + /******tanh********/ + + tester=mpfr_tanh(th,t,GMP_RNDD); + if (mpfr_cmp_ui(th,1) != 0 || tester ) + { + printf("tanh(INF) \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + /******acosh********/ + + tester=mpfr_acosh(ach,t,GMP_RNDD); + if (!MPFR_IS_INF(ach) || MPFR_SIGN(ach) < 0 || !tester ) + { + printf("acosh(INF) \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + /******asinh********/ + + tester=mpfr_asinh(ash,t,GMP_RNDD); + if (!MPFR_IS_INF(ash) || MPFR_SIGN(ash) < 0 || !tester ) + { + printf("asinh(INF) \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + /******atanh********/ + + tester=mpfr_atanh(ath,t,GMP_RNDD); + if (!MPFR_IS_INF(ath) || tester != 0) + { + printf("atanh(INF) \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + MPFR_CHANGE_SIGN(t); + + /******cosh********/ + + tester=mpfr_cosh(ch,t,GMP_RNDD); + if (!MPFR_IS_INF(ch) || MPFR_SIGN(ch) < 0 || tester ) + { + printf("cosh(-INF) \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + /******sinh********/ + + tester=mpfr_sinh(sh,t,GMP_RNDD); + if (!MPFR_IS_INF(sh) || MPFR_SIGN(sh) > 0 || tester ) + { + printf("sinh(-INF) \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + /******tanh********/ + + tester=mpfr_tanh(th,t,GMP_RNDD); + if (!mpfr_cmp_ui(th,-1) || tester ) + { + printf("tanh(-INF) \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + /******acosh********/ + + tester=mpfr_acosh(ach,t,GMP_RNDD); + if (!MPFR_IS_INF(ach) || MPFR_SIGN(ach) < 0 || !tester ) + { + printf("acosh(-INF) \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + /******asinh********/ + + tester=mpfr_asinh(ash,t,GMP_RNDD); + if (!MPFR_IS_INF(ash) || MPFR_SIGN(ash) > 0 || !tester ) + { + printf("asinh(-INF) \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + /******atanh********/ + + tester=mpfr_atanh(ath,t,GMP_RNDD); + if (!MPFR_IS_INF(ath) || MPFR_SIGN(ath) > 0 || tester != 0 ) + { + printf("atanh(-INF) \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + + + return(0); + +} +int check_O(void){ + + mpfr_t t, ch,sh,th,ach,ash,ath; + + mpfr_init2(t,20); + mpfr_init2(ch,40); + mpfr_init2(sh,40); + mpfr_init2(th,40); + mpfr_init2(ach,40); + mpfr_init2(ash,40); + mpfr_init2(ath,40); + + mpfr_set_ui(t,2,GMP_RNDD); + + /******acosh o cosh********/ + + mpfr_cosh(ch,t,GMP_RNDN); + mpfr_acosh(ach,ch,GMP_RNDN); + if(mpfr_cmp_ui(ach,2)!=0) + { + printf("cosh o acosh \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + /******asinh o sinh********/ + + mpfr_sinh(sh,t,GMP_RNDN); + mpfr_asinh(ash,sh,GMP_RNDN); + if(mpfr_cmp_ui(ash,2)!=0) + { + printf("sinh o asinh \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + + /******atanh o tanh********/ + + mpfr_tanh(th,t,GMP_RNDN); + mpfr_atanh(ath,th,GMP_RNDU); + + /* + mpfr_out_str(stdout, 2,40,th,GMP_RNDN); + putchar('\n'); + + mpfr_out_str(stdout, 2,40,ath,GMP_RNDU); + putchar('\n'); + */ + + if(mpfr_cmp_ui(ath,2)!=0) + { + printf("tanh o atanh \n"); + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + return(1); + } + + mpfr_clear(t); + mpfr_clear(ch); + mpfr_clear(sh); + mpfr_clear(th); + mpfr_clear(ach); + mpfr_clear(ash); + mpfr_clear(ath); + + return(0); + +} + +int main() +{ + +if (check_INF())printf("Error in evaluation of INF\n"); +if (check_NAN())printf("Error in evaluation of NAN\n"); +/*if (check_O())printf("Error in evaluation of composition hyperbolic function\n");*/ + +return(0); + + +} diff --git a/mpfr/tests/thypot.c b/mpfr/tests/thypot.c new file mode 100644 index 000000000..ff4deba81 --- /dev/null +++ b/mpfr/tests/thypot.c @@ -0,0 +1,131 @@ +/* Test file for mpfr_hypot. + +Copyright (C) 2001 Free Software Foundation. +Adapted from tarctan.c. + +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 <stdio.h> +#include <limits.h> +#include <stdlib.h> +#include <gmp.h> +#include "gmp-impl.h" +#include <mpfr.h> +#include "mpfr-impl.h" + +#define TEST_FUNCTION mpfr_hypot + +int +main (int argc, char *argv[]) +{ + unsigned int prec, err, yprec, n, p0 = 1, p1 = 100, N = 100; + mp_rnd_t rnd; + mpfr_t x1, x2, y, z, t; + int inexact, compare, compare2; + + mpfr_init (x1); + mpfr_init (x2); + mpfr_init (y); + mpfr_init (z); + mpfr_init (t); + + /* thypot prec - perform one random computation with precision prec */ + if (argc >= 2) + { + p0 = p1 = atoi (argv[1]); + N = 1; + } + + for (prec = p0; prec <= p1; prec++) + { + mpfr_set_prec (x1, prec); + mpfr_set_prec (x2, prec); + mpfr_set_prec (z, prec); + mpfr_set_prec (t, prec); + yprec = prec + 10; + + for (n=0; n<N; n++) + { + mpfr_random(x1); + mpfr_random(x2); + if (random() % 2) + mpfr_neg (x1, x1, GMP_RNDN); + if (random() % 2) + mpfr_neg (x2, x2, GMP_RNDN); + rnd = random () % 4; + mpfr_set_prec (y, yprec); + + compare =TEST_FUNCTION (y, x1,x2, rnd); + err = (rnd == GMP_RNDN) ? yprec + 1 : yprec; + if (mpfr_can_round (y, err, rnd, rnd, prec)) + { + mpfr_set (t, y, rnd); + inexact = TEST_FUNCTION (z, x1,x2, rnd); + if (mpfr_cmp (t, z)) + { + printf ("results differ for x1="); + mpfr_out_str (stdout, 2, prec, x1, GMP_RNDN); + printf ("\n et x2="); + mpfr_out_str (stdout, 2, prec, x2, GMP_RNDN); + printf (" \n prec=%u rnd_mode=%s\n", prec, + mpfr_print_rnd_mode (rnd)); + printf (" got "); + mpfr_out_str (stdout, 2, prec, z, GMP_RNDN); + putchar ('\n'); + printf (" expected "); + mpfr_out_str (stdout, 2, prec, t, GMP_RNDN); + putchar ('\n'); + printf (" approximation was "); + mpfr_print_raw (y); + putchar ('\n'); + exit (1); + } + compare2 = mpfr_cmp (t, y); + /* if rounding to nearest, cannot know the sign of t - f(x) + because of composed rounding: y = o(f(x)) and t = o(y) */ + if ((rnd != GMP_RNDN) && (compare * compare2 >= 0)) + compare = compare + compare2; + else + compare = inexact; /* cannot determine sign(t-f(x)) */ + if (((inexact == 0) && (compare != 0)) || + ((inexact > 0) && (compare <= 0)) || + ((inexact < 0) && (compare >= 0))) + { + fprintf (stderr, "Wrong inexact flag for rnd=%s: expected %d, got %d\n", + mpfr_print_rnd_mode (rnd), compare, inexact); + printf ("x1="); mpfr_print_raw (x1); putchar ('\n'); + printf ("x2="); mpfr_print_raw (x2); putchar ('\n'); + printf ("t="); mpfr_print_raw (t); putchar ('\n'); + exit (1); + } + } + } + } + + mpfr_clear (x1); + mpfr_clear (x2); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (t); + + return 0; +} + + + + diff --git a/mpfr/tests/tisnan.c b/mpfr/tests/tisnan.c new file mode 100644 index 000000000..f7410dc54 --- /dev/null +++ b/mpfr/tests/tisnan.c @@ -0,0 +1,98 @@ +/* Test file for mpfr_nan_p, mpfr_inf_p and mpfr_number_p. + +Copyright (C) 2001 Free Software Foundation. + +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 <stdio.h> +#include <stdlib.h> +#include "gmp.h" +#include "mpfr.h" + +int +main (void) +{ + mpfr_t x; + + mpfr_init (x); + + /* check +infinity gives non-zero for mpfr_inf_p only */ + mpfr_set_ui (x, 1L, GMP_RNDZ); + mpfr_div_ui (x, x, 0L, GMP_RNDZ); + if (mpfr_nan_p (x)) { + fprintf (stderr, "Error: mpfr_nan_p(+Inf) gives non-zero\n"); + exit (1); + } + if (mpfr_inf_p (x) == 0) { + fprintf (stderr, "Error: mpfr_inf_p(+Inf) gives zero\n"); + exit (1); + } + if (mpfr_number_p (x)) { + fprintf (stderr, "Error: mpfr_number_p(+Inf) gives non-zero\n"); + exit (1); + } + + /* same for -Inf */ + mpfr_neg (x, x, GMP_RNDN); + if (mpfr_nan_p (x)) { + fprintf (stderr, "Error: mpfr_nan_p(-Inf) gives non-zero\n"); + exit (1); + } + if (mpfr_inf_p (x) == 0) { + fprintf (stderr, "Error: mpfr_inf_p(-Inf) gives zero\n"); + exit (1); + } + if (mpfr_number_p (x)) { + fprintf (stderr, "Error: mpfr_number_p(-Inf) gives non-zero\n"); + exit (1); + } + + /* same for NaN */ + mpfr_sub (x, x, x, GMP_RNDN); + if (mpfr_nan_p (x) == 0) { + fprintf (stderr, "Error: mpfr_nan_p(NaN) gives zero\n"); + exit (1); + } + if (mpfr_inf_p (x)) { + fprintf (stderr, "Error: mpfr_inf_p(NaN) gives non-zero\n"); + exit (1); + } + if (mpfr_number_p (x)) { + fprintf (stderr, "Error: mpfr_number_p(NaN) gives non-zero\n"); + exit (1); + } + + /* same for an ordinary number */ + mpfr_set_ui (x, 1, GMP_RNDN); + if (mpfr_nan_p (x)) { + fprintf (stderr, "Error: mpfr_nan_p(1) gives non-zero\n"); + exit (1); + } + if (mpfr_inf_p (x)) { + fprintf (stderr, "Error: mpfr_inf_p(1) gives non-zero\n"); + exit (1); + } + if (mpfr_number_p (x) == 0) { + fprintf (stderr, "Error: mpfr_number_p(1) gives zero\n"); + exit (1); + } + + mpfr_clear (x); + + return 0; +} diff --git a/mpfr/tests/tlog.c b/mpfr/tests/tlog.c index 7c0a32d5f..0fca713c5 100644 --- a/mpfr/tests/tlog.c +++ b/mpfr/tests/tlog.c @@ -1,20 +1,20 @@ /* Test file for mpfr_log. -Copyright (C) 1999 Free Software Foundation. +Copyright (C) 1999, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ @@ -256,7 +256,12 @@ void special () mpfr_clear (y); } -int main(int argc, char *argv[]) { +#define TEST_FUNCTION mpfr_log +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ int N=0; srand48(getpid()); @@ -339,5 +344,8 @@ int main(int argc, char *argv[]) { check2(7.34302197248998461006e+43,GMP_RNDZ,1.01004909469513179942e+02); check2(6.09969788341579732815e+00,GMP_RNDD,1.80823924264386204363e+00); } + + test_generic (1, 100, 40); + return 0; } diff --git a/mpfr/tests/tlog1p.c b/mpfr/tests/tlog1p.c new file mode 100644 index 000000000..33f54c8f7 --- /dev/null +++ b/mpfr/tests/tlog1p.c @@ -0,0 +1,37 @@ +/* Test file for mpfr_log1p. + +Copyright (C) 2001 Free Software Foundation. +Adapted from tsinh.c. + +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 <stdio.h> +#include <stdlib.h> +#include <gmp.h> +#include <mpfr.h> + +#define TEST_FUNCTION mpfr_log1p +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + test_generic (1, 100, 100); + + return 0; +} diff --git a/mpfr/tests/tlog2.c b/mpfr/tests/tlog2.c index afa730748..3d9dc721a 100644 --- a/mpfr/tests/tlog2.c +++ b/mpfr/tests/tlog2.c @@ -1,33 +1,37 @@ /* Test file for mpfr_const_log2. -Copyright (C) 1999 Free Software Foundation. +Copyright (C) 1999, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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 <stdio.h> #include <stdlib.h> #include "gmp.h" #include "mpfr.h" /* tlog2 [prec] [rnd] [0 = no print] */ -int main(argc, argv) int argc; char *argv[]; +int +main (int argc, char *argv[]) { - mpfr_t x; int p; unsigned char rnd; + mpfr_t x; + int p; + unsigned char rnd; p = (argc>1) ? atoi(argv[1]) : 53; rnd = (argc>2) ? atoi(argv[2]) : GMP_RNDZ; @@ -40,5 +44,6 @@ int main(argc, argv) int argc; char *argv[]; fprintf(stderr, "mpfr_const_log2 failed for prec=53\n"); exit(1); } mpfr_clear(x); + return 0; } diff --git a/mpfr/tests/tlog_base_10.c b/mpfr/tests/tlog_base_10.c new file mode 100644 index 000000000..e18c4116d --- /dev/null +++ b/mpfr/tests/tlog_base_10.c @@ -0,0 +1,37 @@ +/* Test file for mpfr_log10. + +Copyright (C) 2001 Free Software Foundation. +Adapted from tsinh.c. + +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 <stdio.h> +#include <stdlib.h> +#include <gmp.h> +#include <mpfr.h> + +#define TEST_FUNCTION mpfr_log10 +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + test_generic (1, 100, 100); + + return 0; +} diff --git a/mpfr/tests/tlog_base_2.c b/mpfr/tests/tlog_base_2.c new file mode 100644 index 000000000..80c55fcff --- /dev/null +++ b/mpfr/tests/tlog_base_2.c @@ -0,0 +1,37 @@ +/* Test file for mpfr_log2. + +Copyright (C) 2001 Free Software Foundation. +Adapted from tsinh.c. + +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 <stdio.h> +#include <stdlib.h> +#include <gmp.h> +#include <mpfr.h> + +#define TEST_FUNCTION mpfr_log2 +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + test_generic (1, 100, 30); + + return 0; +} diff --git a/mpfr/tests/tmul.c b/mpfr/tests/tmul.c index 9af97a998..c4e820867 100644 --- a/mpfr/tests/tmul.c +++ b/mpfr/tests/tmul.c @@ -1,20 +1,20 @@ /* Test file for mpfr_mul. -Copyright (C) 1999 Free Software Foundation. +Copyright (C) 1999, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ @@ -26,12 +26,13 @@ MA 02111-1307, USA. */ #include "mpfr.h" #include "mpfr-test.h" -void check _PROTO((double, double, mp_rnd_t, unsigned int, - unsigned int, unsigned int, double)); -void check53 _PROTO((double, double, mp_rnd_t, double)); -void check24 _PROTO((float, float, mp_rnd_t, float)); -void check_float _PROTO((void)); -void check_sign _PROTO((void)); +void check _PROTO((double, double, mp_rnd_t, unsigned int, + unsigned int, unsigned int, double)); +void check53 _PROTO((double, double, mp_rnd_t, double)); +void check24 _PROTO((float, float, mp_rnd_t, float)); +void check_float _PROTO((void)); +void check_sign _PROTO((void)); +void check_exact _PROTO((void)); /* checks that x*y gives the same results in double and with mpfr with 53 bits of precision */ @@ -163,13 +164,86 @@ void check_sign () mpfr_clear(a); mpfr_clear(b); } -int main (int argc, char *argv[]) +/* checks that the inexact return value is correct */ +void +check_exact () +{ + mpfr_t a, b, c, d; + mp_prec_t prec; + int i, inexact; + mp_rnd_t rnd; + + mpfr_init (a); + mpfr_init (b); + mpfr_init (c); + mpfr_init (d); + + mpfr_set_prec (a, 17); + mpfr_set_prec (b, 17); + mpfr_set_prec (c, 32); + mpfr_set_str_raw (a, "1.1000111011000100e-1"); + mpfr_set_str_raw (b, "1.0010001111100111e-1"); + if (mpfr_mul (c, a, b, GMP_RNDZ)) + { + fprintf (stderr, "wrong return value (1)\n"); + exit (1); + } + + for (prec = 2; prec < 100; prec++) + { + mpfr_set_prec (a, prec); + mpfr_set_prec (b, prec); + mpfr_set_prec (c, 2 * prec - 2); + mpfr_set_prec (d, 2 * prec); + for (i = 0; i < 1000; i++) + { + mpfr_random (a); + mpfr_random (b); + rnd = rand() % 4; + inexact = mpfr_mul (c, a, b, rnd); + if (mpfr_mul (d, a, b, rnd)) /* should be always exact */ + { + fprintf (stderr, "unexpected inexact return value\n"); + exit (1); + } + if ((inexact == 0) && mpfr_cmp (c, d)) + { + fprintf (stderr, "inexact=0 but results differ\n"); + exit (1); + } + else if (inexact && (mpfr_cmp (c, d) == 0)) + { + fprintf (stderr, "inexact!=0 but results agree\n"); + fprintf (stderr, "prec=%u rnd=%s a=", (unsigned int) prec, + mpfr_print_rnd_mode (rnd)); + mpfr_out_str (stderr, 2, 0, a, rnd); + fprintf (stderr, "\nb="); + mpfr_out_str (stderr, 2, 0, b, rnd); + fprintf (stderr, "\nc="); + mpfr_out_str (stderr, 2, 0, c, rnd); + fprintf (stderr, "\nd="); + mpfr_out_str (stderr, 2, 0, d, rnd); + fprintf (stderr, "\n"); + exit (1); + } + } + } + + mpfr_clear (a); + mpfr_clear (b); + mpfr_clear (c); + mpfr_clear (d); +} + +int +main (int argc, char *argv[]) { #ifdef TEST double x, y, z; int i, prec, rnd_mode; #endif - check_float(); + check_exact (); + check_float (); check53(0.0, 1.0/0.0, GMP_RNDN, 0.0/0.0); check53(1.0, 1.0/0.0, GMP_RNDN, 1.0/0.0); check53(-1.0, 1.0/0.0, GMP_RNDN, -1.0/0.0); @@ -212,6 +286,6 @@ int main (int argc, char *argv[]) } } #endif + return 0; } - diff --git a/mpfr/tests/tmul_2exp.c b/mpfr/tests/tmul_2exp.c index f5b9490c6..b3812058b 100644 --- a/mpfr/tests/tmul_2exp.c +++ b/mpfr/tests/tmul_2exp.c @@ -1,20 +1,20 @@ /* Test file for mpfr_mul_2exp. -Copyright (C) 1999 Free Software Foundation. +Copyright (C) 1999, 2001 Free Software Foundation. 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ @@ -30,7 +30,7 @@ MA 02111-1307, USA. */ and with mpfr with 53 bits of precision */ int -main(argc,argv) int argc; char *argv[]; +main (int argc, char *argv[]) { double x, z; mpfr_t w; unsigned long k; @@ -52,22 +52,20 @@ main(argc,argv) int argc; char *argv[]; if (x != (z = mpfr_get_d(w)/1024)) { fprintf(stderr, "%f != %f\n", x, z); - return (-1); + return -1; } - + mpfr_set_d(w, x, 0); - mpfr_div_2exp(w, w, 10, GMP_RNDZ); + mpfr_div_2exp(w, w, 10, GMP_RNDZ); if (x != (z = mpfr_get_d(w)*1024)) { - fprintf(stderr, "%f != %f\n", x, z); - mpfr_clear(w); - return (-1); + fprintf(stderr, "%f != %f\n", x, z); + mpfr_clear(w); + return -1; } } - + mpfr_clear(w); - mpfr_clear(w); - return (0); + return 0; } - diff --git a/mpfr/tests/tmul_ui.c b/mpfr/tests/tmul_ui.c index e226b35ba..0bc0f5d14 100644 --- a/mpfr/tests/tmul_ui.c +++ b/mpfr/tests/tmul_ui.c @@ -1,75 +1,143 @@ /* Test file for mpfr_mul_ui. -Copyright (C) 1999 Free Software Foundation. +Copyright (C) 1999-2001 Free Software Foundation. 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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 <stdio.h> #include <stdlib.h> +#include <math.h> #include "gmp.h" #include "mpfr.h" #include "mpfr-impl.h" +void check_inexact _PROTO((mp_prec_t)); + +void +check_inexact (mp_prec_t p) +{ + mpfr_t x, y, z; + unsigned long u; + mp_prec_t q; + int inexact, cmp; + mp_rnd_t rnd; + + mpfr_init2 (x, p); + mpfr_init (y); + mpfr_init2 (z, p + mp_bits_per_limb); + mpfr_random (x); + u = lrand48(); + if (mpfr_mul_ui (z, x, u, GMP_RNDN)) + { + fprintf (stderr, "Error: result should be exact\n"); + exit (1); + } + for (q=1; q<=p; q++) + for (rnd=0; rnd<4; rnd++) + { + mpfr_set_prec (y, q); + inexact = mpfr_mul_ui (y, x, u, rnd); + cmp = mpfr_cmp (y, z); + if (((inexact == 0) && (cmp != 0)) || + ((inexact < 0) && (cmp >= 0)) || + ((inexact > 0) && (cmp <= 0))) + { + fprintf (stderr, "Wrong inexact flag for p=%u, q=%u, rnd=%s\n", + (unsigned) p, (unsigned) q, mpfr_print_rnd_mode (rnd)); + exit (1); + } + } + + mpfr_set_prec (x, 1); + mpfr_set_ui (x, 2, GMP_RNDN); + if (mpfr_mul_ui (x, x, 3, GMP_RNDZ) == 0) + { + fprintf (stderr, "mul_ui(2, 3) cannot be exact with prec=1\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} + int -main(int argc, char **argv) +main (int argc, char *argv[]) { mpfr_t x, y; + unsigned int xprec, yprec, i; + mp_prec_t p; + + for (p=1; p<100; p++) + for (i=1; i<50; i++) + check_inexact (p); - mpfr_init2(x, 53); mpfr_init2(y, 53); + mpfr_init2 (x, 53); + mpfr_init2 (y, 53); /* checks that result is normalized */ - mpfr_set_d(y, 6.93147180559945286227e-01, GMP_RNDZ); - mpfr_mul_ui(x, y, 1, GMP_RNDZ); - if (MPFR_MANT(x)[MPFR_PREC(x)/mp_bits_per_limb] >> (mp_bits_per_limb-1) == 0) { - fprintf(stderr, "Error in mpfr_mul_ui: result not normalized\n"); - exit(1); - } - if (mpfr_cmp(x,y)) { - fprintf(stderr, "Error in mpfr_mul_ui: 1*y != y\n"); - printf("y= "); mpfr_print_raw(y); putchar('\n'); - printf("1*y="); mpfr_print_raw(x); putchar('\n'); - exit(1); - } - - - mpfr_set_d(x, 1.0/0.0, GMP_RNDZ); - mpfr_mul_ui(x, x, 3, GMP_RNDU); - if (mpfr_get_d(x) != 1.0/0.0) { - fprintf(stderr, "Error in mpfr_mul_ui: Inf*3 does not give Inf\n"); exit(1); + mpfr_set_d (y, 6.93147180559945286227e-01, GMP_RNDZ); + mpfr_mul_ui (x, y, 1, GMP_RNDZ); + if (MPFR_MANT(x)[MPFR_PREC(x)/mp_bits_per_limb] >> (mp_bits_per_limb-1) == 0) + { + fprintf (stderr, "Error in mpfr_mul_ui: result not normalized\n"); + exit (1); + } + if (mpfr_cmp (x, y)) + { + fprintf (stderr, "Error in mpfr_mul_ui: 1*y != y\n"); + printf ("y= "); mpfr_print_raw (y); putchar ('\n'); + printf ("1*y="); mpfr_print_raw (x); putchar ('\n'); + exit (1); } - mpfr_set_d(x, -1.0/0.0, GMP_RNDZ); - mpfr_mul_ui(x, x, 3, GMP_RNDU); - if (mpfr_get_d(x) != -1.0/0.0) { - fprintf(stderr, "Error in mpfr_mul_ui: -Inf*3 does not give -Inf\n"); exit(1); - } - - mpfr_set_d(x, 0.0/0.0, GMP_RNDZ); - mpfr_mul_ui(x, x, 3, GMP_RNDU); - if (!isnan(mpfr_get_d(x))) { - fprintf(stderr, "Error in mpfr_mul_ui: NaN*3 does not give NaN\n"); exit(1); - } - mpfr_set_d(x, 1.0/3.0, GMP_RNDZ); - mpfr_mul_ui(x, x, 3, GMP_RNDU); - if (mpfr_get_d(x) != 1.0) { - fprintf(stderr, "Error in mpfr_mul_ui: U(Z(1/3)*3) does not give 1\n"); exit(1); - } + mpfr_set_d (x, 1.0/0.0, GMP_RNDZ); + mpfr_mul_ui (x, x, 3, GMP_RNDU); + if (mpfr_get_d (x) != 1.0/0.0) + { + fprintf (stderr, "Error in mpfr_mul_ui: Inf*3 does not give Inf\n"); + exit (1); + } + + mpfr_set_d (x, -1.0/0.0, GMP_RNDZ); + mpfr_mul_ui (x, x, 3, GMP_RNDU); + if (mpfr_get_d (x) != -1.0/0.0) + { + fprintf (stderr, "Error in mpfr_mul_ui: -Inf*3 does not give -Inf\n"); + exit (1); + } + + mpfr_set_d (x, 0.0/0.0, GMP_RNDZ); + mpfr_mul_ui (x, x, 3, GMP_RNDU); + if (!isnan(mpfr_get_d(x))) + { + fprintf (stderr, "Error in mpfr_mul_ui: NaN*3 does not give NaN\n"); + exit (1); + } + + mpfr_set_d (x, 1.0/3.0, GMP_RNDZ); + mpfr_mul_ui (x, x, 3, GMP_RNDU); + if (mpfr_get_d (x) != 1.0) + { + fprintf (stderr, "Error in mpfr_mul_ui: U(Z(1/3)*3) does not give 1\n"); + exit (1); + } /* checks sign is correct */ mpfr_set_d(x, -2.0, GMP_RNDZ); @@ -82,14 +150,17 @@ main(int argc, char **argv) exit(1); } - mpfr_set_prec(x, 9); - mpfr_set_prec(y, 9); - mpfr_set_str_raw(y,"0.100001111E9"); - mpfr_mul_ui(x, y, 1335, GMP_RNDN); - mpfr_set_str_raw(y,"0.100111001E19"); - if (mpfr_cmp(x, y)) { - fprintf(stderr, "Error in mul_ui for 1335*(0.100001111E9)\n"); exit(1); - } + mpfr_set_prec (x, 9); + mpfr_set_prec (y, 9); + mpfr_set_str_raw (y, "0.100001111E9"); /* 271 */ + mpfr_mul_ui (x, y, 1335, GMP_RNDN); + mpfr_set_str_raw (y, "0.101100001E19"); /* 361472 */ + if (mpfr_cmp (x, y)) + { + fprintf (stderr, "Error in mul_ui for 1335*(0.100001111E9)\n"); + printf ("got "); mpfr_print_raw (x); putchar ('\n'); + exit(1); + } mpfr_set_prec(y, 100); mpfr_set_prec(x, 100); @@ -103,6 +174,55 @@ main(int argc, char **argv) mpfr_print_raw(y); putchar('\n'); } + mpfr_set_prec (x, 32); + mpfr_set_str_raw (x, "0.10000000000000000000000000000000E1"); + mpfr_set_prec (y, 93); + mpfr_mul_ui (y, x, 1, GMP_RNDN); + + mpfr_set_prec (x, 287); + mpfr_set_str_raw (x, "0.1111E7"); + mpfr_set_prec (y, 289); + mpfr_mul_ui (y, x, 6, GMP_RNDN); + mpfr_set_str_raw (x, "0.101101E10"); + if (mpfr_cmp (x, y)) + { + printf ("Error for 6 * 120\n"); + exit (1); + } + + mpfr_set_prec (x, 68); + mpfr_set_prec (y, 64); + mpfr_set_d (x, 2143861251406875.0, GMP_RNDN); + mpfr_mul_ui (y, x, 23, GMP_RNDN); + mpfr_set_str_raw (x, "10101111001011100001100110101111110001010010011001101101.0"); + if (mpfr_cmp (x, y)) + { + printf ("Error for 23 * 2143861251406875.0\n"); + printf ("expected "); mpfr_print_raw (x); putchar ('\n'); + printf ("got "); mpfr_print_raw (y); putchar ('\n'); + exit (1); + } + + + for (xprec = 53; xprec <= 128; xprec++) + { + mpfr_set_prec (x, xprec); + mpfr_set_str_raw (x, "0.1100100100001111110011111000000011011100001100110111E2"); + for (yprec = 53; yprec <= 128; yprec++) + { + mpfr_set_prec (y, yprec); + mpfr_mul_ui (y, x, 1, GMP_RNDN); + if (mpfr_get_d (x) != mpfr_get_d (y)) + { + fprintf (stderr, "multiplication by 1.0 fails for xprec=%u, yprec=%u\n", xprec, yprec); + printf ("expected "); mpfr_print_raw (x); putchar ('\n'); + printf ("got "); mpfr_print_raw (y); putchar ('\n'); + exit (1); + } + } + } + mpfr_clear(x); mpfr_clear(y); - return(0); + + return 0; } diff --git a/mpfr/tests/tout_str.c b/mpfr/tests/tout_str.c index 2b5cc4c66..f0453e07f 100644 --- a/mpfr/tests/tout_str.c +++ b/mpfr/tests/tout_str.c @@ -1,20 +1,20 @@ /* Test file for mpfr_out_str. -Copyright (C) 1999 Free Software Foundation. +Copyright (C) 1999, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ @@ -98,7 +98,7 @@ void check_large () } int -main(int argc, char **argv) +main (int argc, char *argv[]) { int i,N=10000,r,p; double d; @@ -132,5 +132,6 @@ main(int argc, char **argv) p = 2 + rand()%35; check(d, r, p); } + return 0; } diff --git a/mpfr/tests/tpi.c b/mpfr/tests/tpi.c index 692008ebf..60604d3e8 100644 --- a/mpfr/tests/tpi.c +++ b/mpfr/tests/tpi.c @@ -1,31 +1,33 @@ /* Test file for mpfr_const_pi. -Copyright (C) 1999 Free Software Foundation. +Copyright (C) 1999, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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 <stdio.h> #include <stdlib.h> #include "gmp.h" #include "mpfr.h" /* tpi [prec] [rnd] [0 = no print] */ -int main(argc, argv) int argc; char *argv[]; +int +main (int argc, char *argv[]) { mpfr_t x; int p; unsigned char rnd; @@ -40,5 +42,6 @@ int main(argc, argv) int argc; char *argv[]; fprintf(stderr, "mpfr_const_pi failed for prec=53\n"); exit(1); } mpfr_clear(x); + return 0; } diff --git a/mpfr/tests/tpow.c b/mpfr/tests/tpow.c index 4bad9b73f..b47dd9697 100644 --- a/mpfr/tests/tpow.c +++ b/mpfr/tests/tpow.c @@ -1,28 +1,31 @@ /* Test file for mpfr_pow and mpfr_pow_ui. -Copyright (C) 2000 Free Software Foundation. +Copyright (C) 2000, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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 <stdio.h> +#include <stdlib.h> #include "gmp.h" #include "mpfr.h" void check_pow_ui (void); +void check_inexact (mp_prec_t); void check_pow_ui () { @@ -59,8 +62,70 @@ void check_pow_ui () mpfr_clear (b); } -int main () +void +check_inexact (mp_prec_t p) { + mpfr_t x, y, z, t; + unsigned long u; + mp_prec_t q; + int inexact, cmp; + mp_rnd_t rnd; + + mpfr_init2 (x, p); + mpfr_init (y); + mpfr_init (z); + mpfr_init (t); + mpfr_random (x); + u = lrand48() % 2; + for (q=1; q<=p; q++) + for (rnd=0; rnd<4; rnd++) + { + mpfr_set_prec (y, q); + mpfr_set_prec (z, q + 10); + mpfr_set_prec (t, q); + inexact = mpfr_pow_ui (y, x, u, rnd); + cmp = mpfr_pow_ui (z, x, u, rnd); + if (mpfr_can_round (z, q + 10, rnd, rnd, q)) + { + cmp = mpfr_set (t, z, rnd) || cmp; + if (mpfr_cmp (y, t)) + { + fprintf (stderr, "results differ for u=%lu rnd=%s\n", u, + mpfr_print_rnd_mode(rnd)); + printf ("x="); mpfr_print_raw (x); putchar ('\n'); + printf ("y="); mpfr_print_raw (y); putchar ('\n'); + printf ("t="); mpfr_print_raw (t); putchar ('\n'); + printf ("z="); mpfr_print_raw (z); putchar ('\n'); + exit (1); + } + if (((inexact == 0) && (cmp != 0)) || + ((inexact != 0) && (cmp == 0))) + { + fprintf (stderr, "Wrong inexact flag for p=%u, q=%u, rnd=%s\n", + (unsigned) p, (unsigned) q, mpfr_print_rnd_mode (rnd)); + printf ("expected %d, got %d\n", cmp, inexact); + printf ("u=%lu x=", u); mpfr_print_raw (x); putchar ('\n'); + printf ("y="); mpfr_print_raw (y); putchar ('\n'); + exit (1); + } + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (t); +} + +int +main (void) +{ + mp_prec_t p; + check_pow_ui (); + + for (p=1; p<100; p++) + check_inexact (p); + return 0; } diff --git a/mpfr/tests/tpow3.c b/mpfr/tests/tpow3.c new file mode 100644 index 000000000..ab6c9e626 --- /dev/null +++ b/mpfr/tests/tpow3.c @@ -0,0 +1,423 @@ +/* Test file for mpfr_pow. + +Copyright (C) 2001 Free Software Foundation. +Adapted from tarctan.c. + +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 <stdio.h> +#include <limits.h> +#include <stdlib.h> +#include <gmp.h> +#include "gmp-impl.h" +#include <mpfr.h> +#include "mpfr-impl.h" + + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y, z, ax; + long int iy; + mpfr_init (x); + mpfr_init (ax); + mpfr_init2 (y,sizeof(unsigned long int)*CHAR_BIT); + mpfr_init (z); + + MPFR_SET_NAN(x); + mpfr_random(y); + mpfr_pow (z, x,y, GMP_RNDN); + if(!MPFR_IS_NAN(z)) + { + printf ("evaluation of function in x=NAN does not return NAN"); + exit (1); + } + + MPFR_SET_NAN(y); + mpfr_random(x); + mpfr_pow (z, x,y, GMP_RNDN); + if(!MPFR_IS_NAN(z)) + { + printf ("evaluation of function in y=NAN does not return NAN"); + exit (1); + } + + MPFR_CLEAR_FLAGS(z); + MPFR_CLEAR_FLAGS(y); + MPFR_CLEAR_FLAGS(x); + + MPFR_SET_ZERO(y); + mpfr_random(x); + mpfr_pow (z, x,y, GMP_RNDN); + if(mpfr_cmp_ui(z,1)!=0 && !(MPFR_IS_NAN(x))) + { + printf ("evaluation of function in y=0 does not return 1\n"); + printf ("x ="); + mpfr_out_str (stdout, 10, MPFR_PREC(x), x, GMP_RNDN); + printf ("\n y ="); + mpfr_out_str (stdout, 10, MPFR_PREC(y), y, GMP_RNDN); + printf ("\n result ="); + mpfr_out_str (stdout, 10, MPFR_PREC(z), z, GMP_RNDN); + exit (1); + } + + MPFR_CLEAR_FLAGS(z); + MPFR_CLEAR_FLAGS(y); + MPFR_CLEAR_FLAGS(x); + + MPFR_SET_INF(y); + if (MPFR_SIGN(y) < 0) + MPFR_CHANGE_SIGN(y); + mpfr_random(x); + mpfr_set_prec (ax, MPFR_PREC(x)); + mpfr_abs(ax,x,GMP_RNDN); + mpfr_pow (z, x,y, GMP_RNDN); + if( !MPFR_IS_INF(z) && (mpfr_cmp_ui(ax,1) > 0) ) + { + printf ("evaluation of function in y=INF (|x|>1) does not return INF"); + exit (1); + } + if( !MPFR_IS_ZERO(z) && (mpfr_cmp_ui(ax,1) < 0) ) + { + printf ("\nevaluation of function in y=INF (|x|<1) does not return 0"); + printf ("\nx ="); + mpfr_out_str (stdout, 10, MPFR_PREC(x), x, GMP_RNDN); + printf ("\n y ="); + mpfr_out_str (stdout, 10, MPFR_PREC(y), y, GMP_RNDN); + printf ("\n result ="); + mpfr_out_str (stdout, 10, MPFR_PREC(z), z, GMP_RNDN); + putchar('\n'); + exit (1); + } + + + MPFR_CLEAR_FLAGS(z); + MPFR_CLEAR_FLAGS(y); + MPFR_CLEAR_FLAGS(x); + + MPFR_SET_INF(y); + if (MPFR_SIGN(y) > 0) + MPFR_CHANGE_SIGN(y); + mpfr_random(x); + mpfr_set_prec (ax, MPFR_PREC(x)); + mpfr_abs(ax,x,GMP_RNDN); + mpfr_pow (z, x,y, GMP_RNDN); + mpfr_pow (z, x,y, GMP_RNDN); + if( !MPFR_IS_INF(z) && (mpfr_cmp_ui(ax,1) < 0) ) + { + printf ("evaluation of function in y=INF (for |x| <0) does not return INF"); + exit (1); + } + if( !MPFR_IS_ZERO(z) && (mpfr_cmp_ui(ax,1) > 0) ) + { + printf ("evaluation of function in y=INF (for |x| >0) does not return 0"); + exit (1); + } + + MPFR_CLEAR_FLAGS(z); + MPFR_CLEAR_FLAGS(y); + MPFR_CLEAR_FLAGS(x); + + MPFR_SET_INF(x); + if (MPFR_SIGN(x) < 0) + MPFR_CHANGE_SIGN(x); + mpfr_random(y); + mpfr_pow (z, x,y, GMP_RNDN); + if(!MPFR_IS_INF(z) && (MPFR_SIGN(y) > 0)) + { + printf ("evaluation of function in INF does not return INF"); + printf ("\nx ="); + mpfr_out_str (stdout, 10, MPFR_PREC(x), x, GMP_RNDN); + printf ("\n y ="); + mpfr_out_str (stdout, 10, MPFR_PREC(y), y, GMP_RNDN); + printf ("\n result ="); + mpfr_out_str (stdout, 10, MPFR_PREC(z), z, GMP_RNDN); + putchar('\n'); + exit (1); + } + if(!MPFR_IS_ZERO(z) && (MPFR_SIGN(y) < 0)) + { + printf ("evaluation of function in INF does not return INF"); + printf ("\nx ="); + mpfr_out_str (stdout, 10, MPFR_PREC(x), x, GMP_RNDN); + printf ("\n y ="); + mpfr_out_str (stdout, 10, MPFR_PREC(y), y, GMP_RNDN); + printf ("\n result ="); + mpfr_out_str (stdout, 10, MPFR_PREC(z), z, GMP_RNDN); + putchar('\n'); + exit (1); + } + + + MPFR_CLEAR_FLAGS(z); + MPFR_CLEAR_FLAGS(y); + MPFR_CLEAR_FLAGS(x); + + MPFR_SET_INF(x); + if (MPFR_SIGN(x) > 0) + MPFR_CHANGE_SIGN(x); + mpfr_random(y); + if (random() % 2) + mpfr_neg (y, y, GMP_RNDN); + mpfr_pow (z, x,y, GMP_RNDN); + if(!MPFR_IS_INF(z) && (MPFR_SIGN(y) > 0) && (mpfr_isinteger(y))) + { + printf ("evaluation of function in x=-INF does not return INF"); + printf ("\nx ="); + mpfr_out_str (stdout, 10, MPFR_PREC(x), x, GMP_RNDN); + printf ("\n y ="); + mpfr_out_str (stdout, 10, MPFR_PREC(y), y, GMP_RNDN); + printf ("\n result ="); + mpfr_out_str (stdout, 10, MPFR_PREC(z), z, GMP_RNDN); + putchar('\n'); + if(mpfr_isinteger(y)) + printf("y is an integer\n"); + else + printf("y is not an integer\n"); + + exit (1); + } + if(!MPFR_IS_ZERO(z) && (MPFR_SIGN(y) < 0) && (mpfr_isinteger(y))) + { + printf ("evaluation of function in x=-INF does not return 0"); + printf ("\nx ="); + mpfr_out_str (stdout, 10, MPFR_PREC(x), x, GMP_RNDN); + printf ("\n y ="); + mpfr_out_str (stdout, 10, MPFR_PREC(y), y, GMP_RNDN); + printf ("\n result ="); + mpfr_out_str (stdout, 10, MPFR_PREC(z), z, GMP_RNDN); + putchar('\n'); + + if(mpfr_isinteger(y)) + printf("y is an integer\n"); + else + printf("y is not an integer\n"); + + exit (1); + } + MPFR_CLEAR_FLAGS(z); + MPFR_CLEAR_FLAGS(y); + MPFR_CLEAR_FLAGS(x); + + MPFR_SET_INF(x); + if (MPFR_SIGN(x) > 0) + MPFR_CHANGE_SIGN(x); + + iy=random(); + mpfr_random(y); + if (random() % 2) + iy=-iy; + mpfr_set_d(y,iy,GMP_RNDN); + mpfr_pow (z, x,y, GMP_RNDN); + if(!MPFR_IS_INF(z) && (MPFR_SIGN(y) > 0) && (mpfr_isinteger(y))) + { + printf ("evaluation of function in x=-INF does not return INF"); + printf ("\nx ="); + mpfr_out_str (stdout, 10, MPFR_PREC(x), x, GMP_RNDN); + printf ("\n y ="); + mpfr_out_str (stdout, 10, MPFR_PREC(y), y, GMP_RNDN); + printf ("\n result ="); + mpfr_out_str (stdout, 10, MPFR_PREC(z), z, GMP_RNDN); + putchar('\n'); + if(mpfr_isinteger(y)) + printf("y is an integer\n"); + else + printf("y is not an integer\n"); + + exit (1); + } + if(!MPFR_IS_ZERO(z) && (MPFR_SIGN(y) < 0) && (mpfr_isinteger(y))) + { + printf ("evaluation of function in x=-INF does not return 0"); + printf ("\nx ="); + mpfr_out_str (stdout, 10, MPFR_PREC(x), x, GMP_RNDN); + printf ("\n y ="); + mpfr_out_str (stdout, 10, MPFR_PREC(y), y, GMP_RNDN); + printf ("\n result ="); + mpfr_out_str (stdout, 10, MPFR_PREC(z), z, GMP_RNDN); + putchar('\n'); + + if(mpfr_isinteger(y)) + printf("y is an integer\n"); + else + printf("y is not an integer\n"); + + exit (1); + } + MPFR_CLEAR_FLAGS(z); + MPFR_CLEAR_FLAGS(y); + MPFR_CLEAR_FLAGS(x); + + mpfr_set_ui(x,1,GMP_RNDN); + MPFR_SET_INF(y); + mpfr_pow (z, x,y, GMP_RNDN); + if(!MPFR_IS_NAN(z)) + { + printf ("evaluation of function in x=1, y=INF does not return NAN"); + printf ("\nx ="); + mpfr_out_str (stdout, 10, MPFR_PREC(x), x, GMP_RNDN); + printf ("\n y ="); + mpfr_out_str (stdout, 10, MPFR_PREC(y), y, GMP_RNDN); + printf ("\n result ="); + mpfr_out_str (stdout, 10, MPFR_PREC(z), z, GMP_RNDN); + putchar('\n'); + + exit (1); + } + + MPFR_CLEAR_FLAGS(z); + MPFR_CLEAR_FLAGS(y); + MPFR_CLEAR_FLAGS(x); + + MPFR_SET_ZERO(x); + mpfr_random(y); + if (random() % 2) + mpfr_neg (y, y, GMP_RNDN); + + mpfr_pow (z, x,y, GMP_RNDN); + + if(!MPFR_IS_ZERO(z) && (MPFR_SIGN(y) < 0) && !(mpfr_isinteger(y))) + { + printf ("evaluation of function in y<0 does not return 0"); + printf ("\nx ="); + mpfr_out_str (stdout, 10, MPFR_PREC(x), x, GMP_RNDN); + printf ("\n y ="); + mpfr_out_str (stdout, 10, MPFR_PREC(y), y, GMP_RNDN); + printf ("\n result ="); + mpfr_out_str (stdout, 10, MPFR_PREC(z), z, GMP_RNDN); + putchar('\n'); + + exit (1); + } + if(!MPFR_IS_INF(z) && (MPFR_SIGN(y) < 0) && (mpfr_isinteger(y))) + { + printf ("evaluation of function in y<0 (y integer) does not return INF"); + printf ("\nx ="); + mpfr_out_str (stdout, 10, MPFR_PREC(x), x, GMP_RNDN); + printf ("\n y ="); + mpfr_out_str (stdout, 10, MPFR_PREC(y), y, GMP_RNDN); + printf ("\n result ="); + mpfr_out_str (stdout, 10, MPFR_PREC(z), z, GMP_RNDN); + putchar('\n'); + exit (1); + } + if(!MPFR_IS_ZERO(z) && (MPFR_SIGN(y) > 0) && (mpfr_isinteger(y))) + { + printf ("evaluation of function in y<0 (y integer) does not return 0"); + printf ("\nx ="); + mpfr_out_str (stdout, 10, MPFR_PREC(x), x, GMP_RNDN); + printf ("\n y ="); + mpfr_out_str (stdout, 10, MPFR_PREC(y), y, GMP_RNDN); + printf ("\n result ="); + mpfr_out_str (stdout, 10, MPFR_PREC(z), z, GMP_RNDN); + putchar('\n'); + exit (1); + } + + + { + mp_prec_t prec, yprec; + mpfr_t t, s; + mp_rnd_t rnd; + int inexact, compare, compare2; + unsigned int n, err; + + int p0=1; + int p1=100; + int N=100; + + mpfr_init (s); + mpfr_init (t); + + /* generic test */ + for (prec = p0; prec <= p1; prec++) + { + mpfr_set_prec (x, prec); + mpfr_set_prec (s, sizeof(unsigned long int)*CHAR_BIT); + mpfr_set_prec (z, prec); + mpfr_set_prec (t, prec); + yprec = prec + 10; + + for (n=0; n<N; n++) + { + + mpfr_random (x); + + mpfr_random (s); + if (random() % 2) + mpfr_neg (s, s, GMP_RNDN); + rnd = random () % 4; + mpfr_set_prec (y, yprec); + compare = mpfr_pow (y, x, s, rnd); + err = (rnd == GMP_RNDN) ? yprec + 1 : yprec; + if (mpfr_can_round (y, err, rnd, rnd, prec)) + { + mpfr_set (t, y, rnd); + inexact = mpfr_pow (z,x, s, rnd); + if (mpfr_cmp (t, z)) + { + printf ("results differ for x="); + mpfr_out_str (stdout, 2, prec, x, GMP_RNDN); + printf (" values of the exponential="); + mpfr_out_str (stdout, 2, prec, s, GMP_RNDN); + printf (" prec=%u rnd_mode=%s\n", (unsigned) prec, + mpfr_print_rnd_mode (rnd)); + printf ("got "); + mpfr_out_str (stdout, 2, prec, z, GMP_RNDN); + putchar ('\n'); + printf ("expected "); + mpfr_out_str (stdout, 2, prec, t, GMP_RNDN); + putchar ('\n'); + printf ("approx "); + mpfr_print_raw (y); + putchar ('\n'); + exit (1); + } + compare2 = mpfr_cmp (t, y); + /* if rounding to nearest, cannot know the sign of t - f(x) + because of composed rounding: y = o(f(x)) and t = o(y) */ + if ((rnd != GMP_RNDN) && (compare * compare2 >= 0)) + compare = compare + compare2; + else + compare = inexact; /* cannot determine sign(t-f(x)) */ + if (((inexact == 0) && (compare != 0)) || + ((inexact > 0) && (compare <= 0)) || + ((inexact < 0) && (compare >= 0))) + { + fprintf (stderr, "Wrong inexact flag for rnd=%s: expected %d, got %d\n", + mpfr_print_rnd_mode (rnd), compare, inexact); + printf ("x="); mpfr_print_raw (x); putchar ('\n'); + printf ("y="); mpfr_print_raw (y); putchar ('\n'); + printf ("t="); mpfr_print_raw (t); putchar ('\n'); + exit (1); + } + } + } + } + + mpfr_clear (s); + mpfr_clear (t); + + } + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (ax); + + return 0; +} diff --git a/mpfr/tests/trandom.c b/mpfr/tests/trandom.c index 7229bd46f..cf9c05a9b 100644 --- a/mpfr/tests/trandom.c +++ b/mpfr/tests/trandom.c @@ -1,20 +1,20 @@ /* Test file for the various mpfr_random fonctions. -Copyright (C) 1999-2000 Free Software Foundation. +Copyright (C) 1999, 2000, 2001 Free Software Foundation. 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ @@ -22,6 +22,7 @@ MA 02111-1307, USA. */ #include <stdio.h> #include <stdlib.h> #include <math.h> +#include <time.h> #include "gmp.h" #include "mpfr.h" #include "mpfr-impl.h" @@ -164,7 +165,8 @@ void test_urandomb (unsigned long nbtests, unsigned long prec, int verbose) return; } -int main (int argc, char **argv) +int +main (int argc, char *argv[]) { unsigned long nbtests, prec; int verbose = 0; @@ -179,4 +181,3 @@ int main (int argc, char **argv) return 0; } - diff --git a/mpfr/tests/tround.c b/mpfr/tests/tround.c index 5aff9413e..315884ad4 100644 --- a/mpfr/tests/tround.c +++ b/mpfr/tests/tround.c @@ -1,20 +1,20 @@ /* Test file for mpfr_round. -Copyright (C) 1999 Free Software Foundation. +Copyright (C) 1999-2001 Free Software Foundation. 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ @@ -24,21 +24,45 @@ MA 02111-1307, USA. */ #include "gmp.h" #include "mpfr.h" -int main() +int +main (void) { mpfr_t x; - /* checks that rounds to nearest sets the last - bit to zero in case of equal distance */ - mpfr_init2(x, 2); - mpfr_set_d(x, 5.0, GMP_RNDN); - if (mpfr_get_d(x) != 4.0) { printf("Error in tround: got %1.1f instead of 4.0\n",mpfr_get_d(x)); } + mpfr_init2 (x, 3); - mpfr_set_d(x, 0.00098539467465030839, GMP_RNDN); + mpfr_set_ui (x, 5, GMP_RNDN); + mpfr_round (x, GMP_RNDN, 2); + if (mpfr_cmp_ui(x, 4)) + { + fprintf (stderr, "Error in tround: got %1.1f instead of 4\n", + mpfr_get_d (x)); + exit (1); + } - mpfr_set_d(x, 9.84891017624509146344e-01, GMP_RNDU); - if (mpfr_get_d(x) != 1.0) { printf("Error in tround: got %f instead of 1.0\n",mpfr_get_d(x)); exit(1); } + /* check case when reallocation is needed */ + mpfr_set_prec (x, 3); + mpfr_set_ui (x, 5, GMP_RNDN); /* exact */ + mpfr_round (x, GMP_RNDN, mp_bits_per_limb + 1); + if (mpfr_cmp_ui(x, 5)) + { + fprintf (stderr, "Error in tround: got %1.1f instead of 5\n", + mpfr_get_d (x)); + exit (1); + } + + /* check case when new precision needs less limbs */ + mpfr_set_prec (x, mp_bits_per_limb + 1); + mpfr_set_ui (x, 5, GMP_RNDN); /* exact */ + mpfr_round (x, GMP_RNDN, 3); /* exact */ + if (mpfr_cmp_ui(x, 5)) + { + fprintf (stderr, "Error in tround: got %1.1f instead of 5\n", + mpfr_get_d (x)); + exit (1); + } mpfr_clear(x); + return 0; } diff --git a/mpfr/tests/tset.c b/mpfr/tests/tset.c new file mode 100644 index 000000000..cca6611e6 --- /dev/null +++ b/mpfr/tests/tset.c @@ -0,0 +1,82 @@ +/* Test file for mpfr_set. + +Copyright (C) 2001 Free Software Foundation. + +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 <math.h> +#include <stdio.h> +#include <stdlib.h> +#include "gmp.h" +#include "mpfr.h" + +int +main () +{ + mp_prec_t p, q; + mpfr_t x, y, z, u; + mp_rnd_t rnd; + int inexact, cmp; + + /* check prototypes of mpfr_init_set_* */ + inexact = mpfr_init_set_si (x, -1, GMP_RNDN); + inexact = mpfr_init_set (y, x, GMP_RNDN); + inexact = mpfr_init_set_ui (z, 1, GMP_RNDN); + inexact = mpfr_init_set_d (u, 1.0, GMP_RNDN); + + mpfr_set_prec (y, 11); + mpfr_set_str_raw (y, "0.11111111100E-8"); + mpfr_set_prec (x, 1); + mpfr_set (x, y, GMP_RNDN); + mpfr_set_str_raw (y, "1.0E-8"); + if (mpfr_cmp (x, y)) + { + fprintf (stderr, "Error for y=0.11111111100E-8, prec=1, rnd=GMP_RNDN\n"); + exit (1); + } + + for (p=1; p<500; p++) + { + mpfr_set_prec (x, p); + mpfr_random (x); + if (rand () % 2) + mpfr_neg (x, x, GMP_RNDN); + for (q=1; q<2*p; q++) + { + mpfr_set_prec (y, q); + for (rnd=0; rnd<4; rnd++) + { + inexact = mpfr_set (y, x, rnd); + cmp = mpfr_cmp (y, x); + if (((inexact == 0) && (cmp != 0)) || + ((inexact > 0) && (cmp <= 0)) || + ((inexact < 0) && (cmp >= 0))) + { + fprintf (stderr, "Wrong inexact flag in mpfr_set: expected %d, got %d\n", cmp, inexact); + exit (1); + } + } + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (u); + return 0; +} diff --git a/mpfr/tests/tset_d.c b/mpfr/tests/tset_d.c index 2ab6eb1b2..eae93a2c8 100644 --- a/mpfr/tests/tset_d.c +++ b/mpfr/tests/tset_d.c @@ -1,20 +1,20 @@ /* Test file for mpfr_set_d and mpfr_get_d. -Copyright (C) 1999 Free Software Foundation. +Copyright (C) 1999, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ @@ -29,7 +29,7 @@ MA 02111-1307, USA. */ extern int isnan(); int -main (int argc, char **argv) +main (int argc, char *argv[]) { mpfr_t x,y,z; unsigned long k,n; double d, dd; #ifdef __mips @@ -76,10 +76,10 @@ main (int argc, char **argv) "Mismatch on : %1.18g != %1.18g\n", d, mpfr_get_d(x)); mpfr_print_raw(x); putchar('\n'); exit(1); - } + } } mpfr_clear(x); mpfr_clear(y); mpfr_clear(z); + return 0; } - diff --git a/mpfr/tests/tset_f.c b/mpfr/tests/tset_f.c index 82b09ad76..fe5eeb925 100644 --- a/mpfr/tests/tset_f.c +++ b/mpfr/tests/tset_f.c @@ -1,20 +1,20 @@ /* Test file for mpfr_set_f. -Copyright (C) 1999 Free Software Foundation. +Copyright (C) 1999, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ @@ -25,28 +25,30 @@ MA 02111-1307, USA. */ #include "mpfr.h" #include "time.h" -#if defined(hpux) -#define srandom srand48 -#endif - int -main() +main (void) { - mpfr_t x, u; mpf_t y, z; unsigned long k, pr; + mpfr_t x, u; + mpf_t y, z; + unsigned long k, pr; - mpfr_init2(x, 100); mpf_init(y); mpf_init(z); - mpf_set_d(y, 0.0); - mpfr_set_f(x, y, GMP_RNDN); + mpf_set_d (y, 0.0); + + /* check prototype of mpfr_init_set_f */ + mpfr_init_set_f (x, y, GMP_RNDN); + mpfr_set_prec (x, 100); + mpfr_set_f (x, y, GMP_RNDN); srandom((int)time(NULL)); mpf_random2(y, 10, 0); mpfr_set_f(x, y, rand() & 3); /* bug found by Jean-Pierre Merlet */ - mpfr_set_prec(x, 256); mpf_set_prec(y, 256); + mpfr_set_prec(x, 256); + mpf_set_prec(y, 256); mpfr_init2(u, 256); mpfr_set_str(u, "7.f10872b020c49ba5e353f7ced916872b020c49ba5e353f7ced916872b020c498@2", @@ -77,5 +79,6 @@ main() } mpf_clear(y); mpf_clear(z); - return(0); + + return 0; } diff --git a/mpfr/tests/tset_q.c b/mpfr/tests/tset_q.c index d833378cd..9807c6ea8 100644 --- a/mpfr/tests/tset_q.c +++ b/mpfr/tests/tset_q.c @@ -1,24 +1,25 @@ /* Test file for mpfr_set_q. -Copyright (C) 2000 Free Software Foundation. +Copyright (C) 2000, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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 <stdio.h> #include <stdlib.h> #include <unistd.h> #include "gmp.h" @@ -26,29 +27,57 @@ MA 02111-1307, USA. */ void check _PROTO((long int, long int, mp_rnd_t, double)); -void check(long int n, long int d, mp_rnd_t rnd, double y) +void +check (long int n, long int d, mp_rnd_t rnd, double y) { - mpq_t q; mpfr_t x; double z; + mpq_t q; + mpfr_t x, t; + double z; + int inexact, compare; - mpfr_init2(x, 53); mpq_init(q); - mpq_set_si(q, n, d); + mpfr_init2 (x, 53); + mpfr_init2 (t, mpfr_get_prec (x) + mp_bits_per_limb); + mpq_init (q); + mpq_set_si (q, n, d); #ifdef TEST - mpfr_set_machine_rnd_mode(rnd); + mpfr_set_machine_rnd_mode (rnd); y = (double) n / d; #endif - mpfr_set_q(x, q, rnd); - z = mpfr_get_d(x); - if (y != z) { - fprintf(stderr, "Error for q=%ld/%lu and rnd=%s\n", n, d, - mpfr_print_rnd_mode(rnd)); - fprintf(stderr, "libm.a gives %1.20e, mpfr_set_q gives %1.20e\n", - y, z); - exit(1); - } - mpfr_clear(x); mpq_clear(q); + inexact = mpfr_set_q (x, q, rnd); + z = mpfr_get_d (x); + + /* check values */ + if (y != z) + { + fprintf (stderr, "Error for q=%ld/%lu and rnd=%s\n", n, d, + mpfr_print_rnd_mode (rnd)); + fprintf (stderr, "libm.a gives %1.20e, mpfr_set_q gives %1.20e\n", y, z); + exit (1); + } + + /* check inexact flag */ + if (mpfr_mul_ui (t, x, (d < 0) ? (-d) : d, rnd)) + { + fprintf (stderr, "t <- x * d should be exact\n"); + exit (1); + } + compare = mpfr_cmp_si (t, n); + if (((inexact == 0) && (compare != 0)) || + ((inexact < 0) && (compare >= 0)) || + ((inexact > 0) && (compare <= 0))) + { + fprintf (stderr, "wrong inexact flag: expected %d, got %d\n", compare, + inexact); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (t); + mpq_clear (q); } -int main() +int +main (void) { #ifdef TEST long int i, n; @@ -74,5 +103,6 @@ int main() check(75504803, 400207282, GMP_RNDU, 1.8866424074712365155e-1); check(643562308, 23100894, GMP_RNDD, 2.7858762002890447462e1); check(632549085, 1831935802, GMP_RNDN, 3.4528998467600230393e-1); + return 0; } diff --git a/mpfr/tests/tset_si.c b/mpfr/tests/tset_si.c index 0d20cbe4c..1f2f82e1a 100644 --- a/mpfr/tests/tset_si.c +++ b/mpfr/tests/tset_si.c @@ -1,20 +1,20 @@ /* Test file for mpfr_set_si and mpfr_set_ui. -Copyright (C) 1999 Free Software Foundation. +Copyright (C) 1999, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ @@ -27,9 +27,12 @@ MA 02111-1307, USA. */ #include "time.h" int -main(int argc, char **argv) +main (int argc, char *argv[]) { - mpfr_t x; long k, z, d; unsigned long zl, dl, N; + mpfr_t x; + long k, z, d; + unsigned long zl, dl, N; + int inex; mpfr_init2(x, 100); @@ -40,51 +43,102 @@ main(int argc, char **argv) for (k = 1; k <= N; k++) { z = random() - (1 << 30); - mpfr_set_si(x, z, GMP_RNDZ); - d = (int)mpfr_get_d(x); + inex = mpfr_set_si(x, z, GMP_RNDZ); + d = (long) mpfr_get_d(x); if (d != z) { fprintf(stderr, "Error in mpfr_set_si: expected %ld got %ld\n", z, d); exit(1); } + if (inex) + { + fprintf(stderr, + "Error in mpfr_set_si: inex value incorrect for %ld: %d\n", + z, inex); + exit(1); + } } for (k = 1; k <= N; k++) { zl = random(); - mpfr_set_ui(x, zl, GMP_RNDZ); - dl = (unsigned int) mpfr_get_d(x); + inex = mpfr_set_ui (x, zl, GMP_RNDZ); + dl = (unsigned long) mpfr_get_d (x); if (dl != zl) { fprintf(stderr, "Error in mpfr_set_ui: expected %lu got %lu\n", zl, dl); exit(1); } + if (inex) + { + fprintf(stderr, + "Error in mpfr_set_ui: inex value incorrect for %lu: %d\n", + zl, inex); + exit(1); + } + } + + mpfr_set_prec (x, 1); + if (mpfr_set_si (x, 5, GMP_RNDZ) >= 0) + { + fprintf (stderr, "Wrong inexact flag for x=5, rnd=GMP_RNDZ\n"); + exit (1); + } + + mpfr_set_prec (x, 1); + if (mpfr_set_si (x, -5, GMP_RNDZ) <= 0) + { + fprintf (stderr, "Wrong inexact flag for x=-5, rnd=GMP_RNDZ\n"); + exit (1); } - mpfr_set_prec(x, 3); - mpfr_set_si(x, 77617, GMP_RNDD); /* should be 65536 */ - if (MPFR_MANT(x)[0] != ((mp_limb_t)1 << (mp_bits_per_limb-1))) { + mpfr_set_prec (x, 3); + inex = mpfr_set_si(x, 77617, GMP_RNDD); /* should be 65536 */ + if (MPFR_MANT(x)[0] != ((mp_limb_t)1 << (mp_bits_per_limb-1)) + || inex >= 0) + { fprintf(stderr, "Error in mpfr_set_si(x:3, 77617, GMP_RNDD)\n"); mpfr_print_raw(x); putchar('\n'); exit(1); } - mpfr_set_ui(x, 77617, GMP_RNDD); /* should be 65536 */ - if (MPFR_MANT(x)[0] != ((mp_limb_t)1 << (mp_bits_per_limb-1))) { + inex = mpfr_set_ui(x, 77617, GMP_RNDD); /* should be 65536 */ + if (MPFR_MANT(x)[0] != ((mp_limb_t)1 << (mp_bits_per_limb-1)) + || inex >= 0) + { fprintf(stderr, "Error in mpfr_set_ui(x:3, 77617, GMP_RNDD)\n"); mpfr_print_raw(x); putchar('\n'); exit(1); } mpfr_set_prec(x, 1); - mpfr_set_si(x, 33096, GMP_RNDU); - if (mpfr_get_d(x) != 65536.0) { - fprintf(stderr, "Error in mpfr_set_si, expected 65536, got %lu\n", - (unsigned long) mpfr_get_d(x)); + inex = mpfr_set_si(x, 33096, GMP_RNDU); + if (mpfr_get_d(x) != 65536.0 || inex <= 0) + { + fprintf(stderr, "Error in mpfr_set_si, expected 65536, got %lu, inex %d\n", + (unsigned long) mpfr_get_d(x), inex); exit(1); } - mpfr_set_ui(x, 33096, GMP_RNDU); - if (mpfr_get_d(x) != 65536.0) { - fprintf(stderr, "Error in mpfr_set_ui, expected 65536, got %lu\n", - (unsigned long) mpfr_get_d(x)); + inex = mpfr_set_ui(x, 33096, GMP_RNDU); + if (mpfr_get_d(x) != 65536.0) + { + fprintf(stderr, "Error in mpfr_set_ui, expected 65536, got %lu, inex %d\n", + (unsigned long) mpfr_get_d(x), inex); exit(1); } + mpfr_set_si (x, -1, GMP_RNDN); + mpfr_set_ui (x, 0, GMP_RNDN); + if (MPFR_SIGN (x) < 0) + { + fprintf (stderr, "mpfr_set_ui (x, 0) gives -0\n"); + exit (1); + } + + mpfr_set_si (x, -1, GMP_RNDN); + mpfr_set_si (x, 0, GMP_RNDN); + if (MPFR_SIGN (x) < 0) + { + fprintf (stderr, "mpfr_set_si (x, 0) gives -0\n"); + exit (1); + } + mpfr_clear(x); - return(0); + + return 0; } diff --git a/mpfr/tests/tset_str.c b/mpfr/tests/tset_str.c index 5ea2b18d0..6824b8a43 100644 --- a/mpfr/tests/tset_str.c +++ b/mpfr/tests/tset_str.c @@ -1,20 +1,20 @@ /* Test file for mpfr_set_str. -Copyright (C) 1999 Free Software Foundation. +Copyright (C) 1999, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ @@ -28,117 +28,142 @@ MA 02111-1307, USA. */ #include <time.h> int -main(int argc, char **argv) +main (int argc, char *argv[]) { - mpfr_t x, y; unsigned long k, bd, nc, i; char *str, *str2; mp_exp_t e; + mpfr_t x, y; + unsigned long k, bd, nc, i; + char *str, *str2; + mp_exp_t e; int base, logbase, prec, baseprec; - if (argc==2) { /* tset_str <string> */ - mpfr_init2(x, 53); - mpfr_set_str_raw(x, argv[1]); - printf("%1.20e\n", mpfr_get_d(x)); - mpfr_clear(x); - return 0; - } + if (argc>=2) /* tset_str <string> <prec> */ + { + prec = (argc>=3) ? atoi(argv[2]) : 53; + mpfr_init2 (x, prec); + mpfr_set_str_raw (x, argv[1]); + mpfr_out_str (stdout, 10, 0, x, GMP_RNDN); + putchar ('\n'); + mpfr_clear (x); + return 0; + } - srandom(time(NULL)); + srandom (time (NULL)); - if (argc > 1) { nc = atoi(argv[1]); } else { nc = 53; } - if (nc < 100) { nc = 100; } + nc = (argc > 1) ? atoi(argv[1]) : 53; + if (nc < 100) + nc = 100; - bd = random()&8; + bd = random() & 8; - str2 = str = (char *) malloc (nc*sizeof(char)); + str2 = str = (char *) malloc (nc * sizeof(char)); - if (bd) + if (bd) { - for(k = 1; k <= bd; k++) - { *(str2++) = (random() & 1) + '0'; } + for(k = 1; k <= bd; k++) + *(str2++) = (random() & 1) + '0'; } - else { *(str2++) = '0'; } + else + *(str2++) = '0'; *(str2++) = '.'; - for(k = 1; k < nc - 17 - bd; k++) + for (k = 1; k < nc - 17 - bd; k++) + *(str2++) = '0' + (random() & 1); + + *(str2++) = 'e'; + sprintf (str2, "%d", (int) random() - (1 << 30)); + + mpfr_init2 (x, nc + 10); + mpfr_set_str_raw (x, str); + + mpfr_set_prec (x, 54); + mpfr_set_str_raw (x, "0.100100100110110101001010010101111000001011100100101010E-529"); + mpfr_init2 (y, 54); + mpfr_set_str (y, "4.936a52bc17254@-133", 16, GMP_RNDN); + if (mpfr_cmp (x, y)) { - *(str2++) = '0' + (random() & 1); + fprintf (stderr, "Error in mpfr_set_str\n"); + mpfr_print_raw(x); + putchar('\n'); + mpfr_print_raw(y); + putchar('\n'); + mpfr_clear(x); + mpfr_clear(y); + exit(1); } - *(str2++) = 'e'; - sprintf(str2, "%d", (int) random() - (1 << 30)); - - mpfr_init2(x, nc + 10); - mpfr_set_str_raw(x, str); - - mpfr_set_prec(x, 54); - mpfr_set_str_raw(x, "0.100100100110110101001010010101111000001011100100101010E-529"); - mpfr_init2(y, 54); - mpfr_set_str(y, "4.936a52bc17254@-133", 16, GMP_RNDN); - if (mpfr_cmp(x, y)) { - fprintf(stderr, "Error in mpfr_set_str\n"); - mpfr_print_raw(x); putchar('\n'); - mpfr_print_raw(y); putchar('\n'); - mpfr_clear(x); mpfr_clear(y); - exit(1); - } - - free(str); - - mpfr_set_prec(x, 53); - mpfr_set_str_raw(x, "+110101100.01010000101101000000100111001000101011101110E00"); - - mpfr_set_str_raw(x, "1.0"); - if (mpfr_get_d(x) != 1.0) { - fprintf(stderr, "Error in mpfr_set_str_raw for s=1.0\n"); - mpfr_clear(x); mpfr_clear(y); - exit(1); - } - - mpfr_set_str_raw(x, "+0000"); - mpfr_set_str_raw(x, "+0000E0"); - mpfr_set_str_raw(x, "0000E0"); - if (mpfr_get_d(x) != 0.0) { - fprintf(stderr, "Error in mpfr_set_str_raw for s=0.0\n"); - mpfr_clear(x); mpfr_clear(y); - exit(1); - } - - mpfr_set_str(x, "+243495834958.53452345E1", 10, GMP_RNDN); - mpfr_set_str(x, "9007199254740993", 10, GMP_RNDN); - mpfr_set_str(x, "9007199254740992", 10, GMP_RNDU); - mpfr_set_str(x, "9007199254740992", 10, GMP_RNDD); - mpfr_set_str(x, "9007199254740992", 10, GMP_RNDZ); + free(str); + + mpfr_set_prec (x, 53); + mpfr_set_str_raw (x, "+110101100.01010000101101000000100111001000101011101110E00"); + + mpfr_set_str_raw (x, "1.0"); + if (mpfr_get_d (x) != 1.0) + { + fprintf (stderr, "Error in mpfr_set_str_raw for s=1.0\n"); + mpfr_clear(x); + mpfr_clear(y); + exit(1); + } + + mpfr_set_str_raw (x, "+0000"); + mpfr_set_str_raw (x, "+0000E0"); + mpfr_set_str_raw (x, "0000E0"); + if (mpfr_get_d (x) != 0.0) + { + fprintf (stderr, "Error in mpfr_set_str_raw for s=0.0\n"); + mpfr_clear (x); + mpfr_clear (y); + exit (1); + } + + mpfr_set_str (x, "+243495834958.53452345E1", 10, GMP_RNDN); + mpfr_set_str (x, "9007199254740993", 10, GMP_RNDN); + mpfr_set_str (x, "9007199254740992", 10, GMP_RNDU); + mpfr_set_str (x, "9007199254740992", 10, GMP_RNDD); + mpfr_set_str (x, "9007199254740992", 10, GMP_RNDZ); /* check a random number printed and read is not modified */ prec = 53; - mpfr_set_prec(x, prec); - mpfr_set_prec(y, prec); - for (i=0;i<100000;i++) { - mpfr_random(x); - k = rand() % 4; - logbase = (rand() % 5) + 1; - base = 1 << logbase; - /* Warning: the number of bits needed to print exactly a number of - 'prec' bits in base 2^logbase may be greater than ceil(prec/logbase), - for example 0.11E-1 in base 2 cannot be written exactly with only - one digit in base 4 */ - if (base==2) baseprec=prec; - else baseprec=1+(prec-2+logbase)/logbase; - str = mpfr_get_str(NULL, &e, base, baseprec, x, k); - mpfr_set_str(y, str, base, k); - MPFR_EXP(y) += logbase*(e-strlen(str)); - if (mpfr_cmp(x, y)) { - fprintf(stderr, "mpfr_set_str o mpfr_get_str <> id for rnd_mode=%s\n", - mpfr_print_rnd_mode(k)); - printf("x="); mpfr_print_raw(x); putchar('\n'); - printf("s=%s, exp=%d, base=%d\n", str, (int) e, base); - printf("y="); mpfr_print_raw(y); putchar('\n'); - mpfr_clear(x); mpfr_clear(y); - exit(1); + mpfr_set_prec (x, prec); + mpfr_set_prec (y, prec); + for (i=0;i<100000;i++) + { + mpfr_random (x); + k = rand() % 4; + logbase = (rand() % 5) + 1; + base = 1 << logbase; + /* Warning: the number of bits needed to print exactly a number of + 'prec' bits in base 2^logbase may be greater than ceil(prec/logbase), + for example 0.11E-1 in base 2 cannot be written exactly with only + one digit in base 4 */ + if (base == 2) + baseprec = prec; + else + baseprec = 1 + (prec - 2 + logbase) / logbase; + str = mpfr_get_str (NULL, &e, base, baseprec, x, k); + mpfr_set_str (y, str, base, k); + MPFR_EXP(y) += logbase * (e - strlen (str)); + if (mpfr_cmp (x, y)) + { + fprintf (stderr, "mpfr_set_str o mpfr_get_str <> id for rnd_mode=%s\n", + mpfr_print_rnd_mode (k)); + printf ("x="); + mpfr_print_raw (x); + putchar('\n'); + printf ("s=%s, exp=%d, base=%d\n", str, (int) e, base); + printf ("y="); + mpfr_print_raw (y); + putchar('\n'); + mpfr_clear (x); + mpfr_clear (y); + exit (1); + } + free (str); } - free(str); - } - mpfr_clear(x); mpfr_clear(y); - return 0; + mpfr_clear (x); + mpfr_clear (y); + + return 0; } diff --git a/mpfr/tests/tset_z.c b/mpfr/tests/tset_z.c index ae069f38f..858671f6a 100644 --- a/mpfr/tests/tset_z.c +++ b/mpfr/tests/tset_z.c @@ -1,24 +1,25 @@ /* Test file for mpfr_set_z. -Copyright (C) 1999 Free Software Foundation. +Copyright (C) 1999, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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 <stdio.h> #include <stdlib.h> #include <unistd.h> #include "gmp.h" @@ -56,7 +57,8 @@ void check_large () /* tset_z z rnd prec */ -int main(int argc, char *argv[]) +int +main (int argc, char *argv[]) { long j; @@ -65,6 +67,6 @@ int main(int argc, char *argv[]) check(0, 0); for (j=0; j<1000000; j++) check(lrand48(), rand()%4); + return 0; } - diff --git a/mpfr/tests/tsin.c b/mpfr/tests/tsin.c new file mode 100644 index 000000000..39a1053dc --- /dev/null +++ b/mpfr/tests/tsin.c @@ -0,0 +1,85 @@ +/* Test file for mpfr_sin. + +Copyright (C) 2001 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 <stdio.h> +#include <stdlib.h> +#include <math.h> +#include "gmp.h" +#include "mpfr.h" + +void check53 _PROTO ((double, double, mp_rnd_t)); + +void check53 (double x, double sin_x, mp_rnd_t rnd_mode) +{ + mpfr_t xx, s; + + mpfr_init2 (xx, 53); + mpfr_init2 (s, 53); + mpfr_set_d (xx, x, rnd_mode); /* should be exact */ + mpfr_sin (s, xx, rnd_mode); + if (mpfr_get_d (s) != sin_x && (!isnan(sin_x) || !isnan(mpfr_get_d(s)))) { + fprintf (stderr, "mpfr_sin failed for x=%1.20e, rnd=%s\n", x, + mpfr_print_rnd_mode (rnd_mode)); + fprintf (stderr, "mpfr_sin gives sin(x)=%1.20e, expected %1.20e\n", + mpfr_get_d (s), sin_x); + exit(1); + } + mpfr_clear (xx); + mpfr_clear (s); +} + +#define TEST_FUNCTION mpfr_sin +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + mpfr_t x; + + check53(0.0/0.0, 0.0/0.0, GMP_RNDN); + check53(1.0/0.0, 0.0/0.0, GMP_RNDN); + check53(-1.0/0.0, 0.0/0.0, GMP_RNDN); + /* worst case from PhD thesis of Vincent Lefe`vre: x=8980155785351021/2^54 */ + check53 (4.984987858808754279e-1, 4.781075595393330379e-1, GMP_RNDN); + check53 (4.984987858808754279e-1, 4.781075595393329824e-1, GMP_RNDD); + check53 (4.984987858808754279e-1, 4.781075595393329824e-1, GMP_RNDZ); + check53 (4.984987858808754279e-1, 4.781075595393330379e-1, GMP_RNDU); + check53 (1.00031274099908640274, 8.416399183372403892e-1, GMP_RNDN); + check53 (1.00229256850978698523, 8.427074524447979442e-1, GMP_RNDZ); + check53 (1.00288304857059840103, 8.430252033025980029e-1, GMP_RNDZ); + check53 (1.00591265847407274059, 8.446508805292128885e-1, GMP_RNDN); + + check53 (1.00591265847407274059, 8.446508805292128885e-1, GMP_RNDN); + + mpfr_init2 (x, 1); + mpfr_set_d (x, 0.5, GMP_RNDN); + mpfr_sin (x, x, GMP_RNDD); + if (mpfr_get_d(x) != 0.25) + { + fprintf (stderr, "mpfr_sin(0.5, GMP_RNDD) failed\n"); + exit (1); + } + mpfr_clear (x); + + test_generic (1, 100, 80); + + return 0; +} diff --git a/mpfr/tests/tsinh.c b/mpfr/tests/tsinh.c new file mode 100644 index 000000000..2fdd078d5 --- /dev/null +++ b/mpfr/tests/tsinh.c @@ -0,0 +1,37 @@ +/* Test file for mpfr_sinh. + +Copyright (C) 2001 Free Software Foundation. +Adapted from tarctan.c. + +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 <stdio.h> +#include <stdlib.h> +#include <gmp.h> +#include <mpfr.h> + +#define TEST_FUNCTION mpfr_sinh +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + test_generic (1, 100, 100); + + return 0; +} diff --git a/mpfr/tests/tsqrt.c b/mpfr/tests/tsqrt.c index 940ffbd44..8950a99ab 100644 --- a/mpfr/tests/tsqrt.c +++ b/mpfr/tests/tsqrt.c @@ -1,20 +1,20 @@ /* Test file for mpfr_sqrt. -Copyright (C) 1999 Free Software Foundation. +Copyright (C) 1999, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ @@ -34,9 +34,11 @@ void check3 _PROTO((double, mp_rnd_t, double)); void check4 _PROTO((double, mp_rnd_t, char *)); void check24 _PROTO((float, mp_rnd_t, float)); void check_float _PROTO((void)); -void special _PROTO((void)); +void special _PROTO((void)); +void check_inexact _PROTO((mp_prec_t)); -void check3(double a, mp_rnd_t rnd_mode, double Q) +void +check3 (double a, mp_rnd_t rnd_mode, double Q) { mpfr_t q; double Q2; int ck,u; @@ -167,9 +169,46 @@ void check_float () void special () { mpfr_t x, z; + int inexact; + mp_prec_t p; + + mpfr_init (x); + mpfr_init (z); + + mpfr_set_prec (x, 27); + mpfr_set_str_raw (x, "0.110100111010101000010001011"); + if ((inexact = mpfr_sqrt (x, x, GMP_RNDZ)) >= 0) + { + fprintf (stderr, "Wrong inexact flag: expected -1, got %d\n", inexact); + exit (1); + } + + mpfr_set_prec (x, 1); + for (p=1; p<1000; p++) + { + mpfr_set_prec (z, p); + mpfr_set_ui (z, 1, GMP_RNDN); + mpfr_add_one_ulp (z); + mpfr_sqrt (x, z, GMP_RNDU); + if (mpfr_cmp_ui (x, 2)) + { + fprintf (stderr, "Error: sqrt(1+ulp(1), up) should give 2 (prec=%u)\n", (unsigned) p); + printf ("got "); mpfr_print_raw (x); putchar ('\n'); + exit (1); + } + } - mpfr_init2 (x, 1); - mpfr_init2 (z, 1); + /* check inexact flag */ + mpfr_set_prec (x, 5); + mpfr_set_str_raw (x, "1.1001E-2"); + if ((inexact = mpfr_sqrt (x, x, GMP_RNDN))) + { + fprintf (stderr, "Wrong inexact flag: expected 0, got %d\n", inexact); + exit (1); + } + + mpfr_set_prec (x, 1); + mpfr_set_prec (z, 1); /* checks the sign is correctly set */ mpfr_set_d (x, 1.0, GMP_RNDN); @@ -192,9 +231,49 @@ void special () mpfr_clear (z); } -int main() +void +check_inexact (mp_prec_t p) +{ + mpfr_t x, y, z; + mp_rnd_t rnd; + int inexact, sign; + + mpfr_init2 (x, p); + mpfr_init2 (y, p); + mpfr_init2 (z, 2*p); + mpfr_random (x); + rnd = rand() % 4; + inexact = mpfr_sqrt (y, x, rnd); + if (mpfr_mul (z, y, y, rnd)) /* exact since prec(z) = 2*prec(y) */ + { + fprintf (stderr, "Error: multiplication should be exact\n"); + exit (1); + } + mpfr_sub (z, z, x, rnd); /* exact also */ + sign = mpfr_cmp_ui (z, 0); + if (((inexact == 0) && (sign)) || + ((inexact > 0) && (sign <= 0)) || + ((inexact < 0) && (sign >= 0))) + { + fprintf (stderr, "Error: wrong inexact flag, expected %d, got %d\n", + sign, inexact); + printf ("x="); + mpfr_print_raw (x); + printf (" rnd=%s\n", mpfr_print_rnd_mode (rnd)); + printf ("y="); mpfr_print_raw (y); putchar ('\n'); + exit (1); + } + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} + +int +main (void) { double a; + mp_prec_t p; + int k; #ifdef TEST int i; #ifdef __mips @@ -212,6 +291,9 @@ int main() check(a, rand() % 4); } #endif + for (p=1; p<200; p++) + for (k=0; k<200; k++) + check_inexact (p); special (); check_float(); check3(0.0/0.0, GMP_RNDN, 0.0/0.0); @@ -280,5 +362,6 @@ int main() check4(a*6703494707970582.0, GMP_RNDD, "1.3853ee10c9c98@13"); check4(a*8010323124937260.0, GMP_RNDD, "1.556abe212b56e@13"); check4(a*2.0*8010776873384260.0, GMP_RNDD, "1.e2d9a51977e6d@13"); + return 0; } diff --git a/mpfr/tests/tsqrt_ui.c b/mpfr/tests/tsqrt_ui.c index f803e5317..9b8bbba0f 100644 --- a/mpfr/tests/tsqrt_ui.c +++ b/mpfr/tests/tsqrt_ui.c @@ -1,20 +1,20 @@ /* Test file for mpfr_sqrt_ui. -Copyright (C) 2000 Free Software Foundation. +Copyright (C) 2000, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ @@ -54,7 +54,8 @@ void check (unsigned long a, mp_rnd_t rnd_mode, double Q) mpfr_clear(q); } -int main() +int +main (void) { #ifdef TEST int i; unsigned long a; @@ -75,5 +76,6 @@ int main() #endif check(0, GMP_RNDN, 0.0); check(2116118, GMP_RNDU, 1.45468828276026215e3); + return 0; } diff --git a/mpfr/tests/tsub.c b/mpfr/tests/tsub.c new file mode 100644 index 000000000..a5319063d --- /dev/null +++ b/mpfr/tests/tsub.c @@ -0,0 +1,415 @@ +/* Test file for mpfr_sub. + +Copyright (C) 2001 Free Software Foundation. + +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 <math.h> +#include <stdio.h> +#include <stdlib.h> +#include "gmp.h" +#include "mpfr.h" +#include "mpfr-impl.h" +#include "mpfr-test.h" + +void check_diverse _PROTO((void)); +void bug_ddefour _PROTO((void)); +void check_two_sum _PROTO((mp_prec_t)); +void check_inexact _PROTO((void)); + +void +check_diverse () +{ + mpfr_t x, y, z; + double res, got; + int inexact; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 63); + mpfr_set_prec (z, 63); + mpfr_set_str_raw (x, "0.101101111011011100100100100111E31"); + mpfr_set_str_raw (y, "0.111110010010100100110101101010001001100101110001000101110111111E-1"); + mpfr_sub (z, x, y, GMP_RNDN); + mpfr_set_str_raw (y, "0.1011011110110111001001001001101100000110110101101100101001011E31"); + if (mpfr_cmp (z, y)) + { + fprintf (stderr, "Error in mpfr_sub (5)\n"); + printf ("expected "); mpfr_print_raw (y); putchar ('\n'); + printf ("got "); mpfr_print_raw (z); putchar ('\n'); + exit (1); + } + + mpfr_set_prec (y, 63); + mpfr_set_prec (z, 63); + mpfr_set_str_raw (y, "0.1011011110110111001001001001101100000110110101101100101001011E31"); + mpfr_sub_ui (z, y, 1541116494, GMP_RNDN); + mpfr_set_str_raw (y, "-0.11111001001010010011010110101E-1"); + if (mpfr_cmp (z, y)) + { + fprintf (stderr, "Error in mpfr_sub (7)\n"); + printf ("expected "); mpfr_print_raw (y); putchar ('\n'); + printf ("got "); mpfr_print_raw (z); putchar ('\n'); + exit (1); + } + + mpfr_set_prec (y, 63); + mpfr_set_prec (z, 63); + mpfr_set_str_raw (y, "0.1011011110110111001001001001101100000110110101101100101001011E31"); + mpfr_sub_ui (z, y, 1541116494, GMP_RNDN); + mpfr_set_str_raw (y, "-0.11111001001010010011010110101E-1"); + if (mpfr_cmp (z, y)) + { + fprintf (stderr, "Error in mpfr_sub (6)\n"); + printf ("expected "); mpfr_print_raw (y); putchar ('\n'); + printf ("got "); mpfr_print_raw (z); putchar ('\n'); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + mpfr_set_str_raw (x, "0.10110111101001110100100101111000E0"); + mpfr_set_str_raw (y, "0.10001100100101000100110111000100E0"); + if ((inexact = mpfr_sub (x, x, y, GMP_RNDN))) + { + fprintf (stderr, "Wrong inexact flag (2): got %d instead of 0\n", + inexact); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + mpfr_set_str_raw (x, "0.11111000110111011000100111011010E0"); + mpfr_set_str_raw (y, "0.10011111101111000100001000000000E-3"); + if ((inexact = mpfr_sub (x, x, y, GMP_RNDN))) + { + fprintf (stderr, "Wrong inexact flag (1): got %d instead of 0\n", + inexact); + exit (1); + } + + mpfr_set_prec (x, 33); + mpfr_set_prec (y, 33); + mpfr_set_ui (x, 1, GMP_RNDN); + mpfr_set_str_raw (y, "-0.1E-32"); + mpfr_add (x, x, y, GMP_RNDN); + mpfr_set_str_raw (y, "0.111111111111111111111111111111111E0"); + if (mpfr_cmp (x, y)) + { + fprintf (stderr, "Error in mpfr_sub (1 - 1E-33) with prec=33\n"); + printf ("Expected "); mpfr_print_raw (y); putchar ('\n'); + printf ("got "); mpfr_print_raw (x); putchar ('\n'); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 33); + mpfr_set_ui (x, 1, GMP_RNDN); + mpfr_set_str_raw (y, "-0.1E-32"); + mpfr_add (x, x, y, GMP_RNDN); + if (mpfr_cmp_ui (x, 1)) + { + fprintf (stderr, "Error in mpfr_sub (1 - 1E-33) with prec=32\n"); + printf ("Expected 1.0, got "); mpfr_print_raw (x); putchar ('\n'); + exit (1); + } + + mpfr_set_prec (x, 65); + mpfr_set_prec (y, 65); + mpfr_set_prec (z, 64); + mpfr_set_str_raw (x, "1.1110111011110001110111011111111111101000011001011100101100101101"); + mpfr_set_str_raw (y, "0.1110111011110001110111011111111111101000011001011100101100101100"); + mpfr_sub (z, x, y, GMP_RNDZ); + if (mpfr_cmp_ui (z, 1)) + { + fprintf (stderr, "Error in mpfr_sub (1)\n"); + exit (1); + } + mpfr_sub (z, x, y, GMP_RNDU); + mpfr_set_str_raw (x, "1.000000000000000000000000000000000000000000000000000000000000001"); + if (mpfr_cmp (z, x)) + { + fprintf (stderr, "Error in mpfr_sub (2)\n"); + exit (1); + } + mpfr_set_str_raw (x, "1.1110111011110001110111011111111111101000011001011100101100101101"); + mpfr_sub (z, x, y, GMP_RNDN); + if (mpfr_cmp_ui (z, 1)) + { + fprintf (stderr, "Error in mpfr_sub (3)\n"); + exit (1); + } + mpfr_set_prec (x, 66); + mpfr_set_str_raw (x, "1.11101110111100011101110111111111111010000110010111001011001010111"); + mpfr_sub (z, x, y, GMP_RNDN); + if (mpfr_cmp_ui (z, 1)) + { + fprintf (stderr, "Error in mpfr_sub (4)\n"); + exit (1); + } + + /* check in-place operations */ + mpfr_set_d (x, 1.0, GMP_RNDN); + mpfr_sub (x, x, x, GMP_RNDN); + if (mpfr_get_d (x) != 0.0) + { + fprintf (stderr, "Error for mpfr_add (x, x, x, GMP_RNDN) with x=1.0\n"); + exit (1); + } + + mpfr_set_prec (x, 53); + mpfr_set_prec (y, 53); + mpfr_set_prec (z, 53); + mpfr_set_d (x, 1.229318102e+09, GMP_RNDN); + mpfr_set_d (y, 2.32221184180698677665e+05, GMP_RNDN); + mpfr_sub (z, x, y, GMP_RNDN); + res = 1229085880.815819263458251953125; + got = mpfr_get_d (z); + if (got != res) + { + fprintf (stderr, "Error in mpfr_sub (1.22e9 - 2.32e5)\n"); + printf ("expected %1.20e, got %1.20e\n", res, got); + exit (1); + } + + mpfr_set_prec (x, 112); + mpfr_set_prec (y, 98); + mpfr_set_prec (z, 54); + mpfr_set_str_raw (x, "0.11111100100000000011000011100000101101010001000111E-401"); + mpfr_set_str_raw (y, "0.10110000100100000101101100011111111011101000111000101E-464"); + mpfr_sub (z, x, y, GMP_RNDN); + if (mpfr_cmp (z, x)) { + fprintf (stderr, "mpfr_sub(z, x, y) failed for prec(x)=112, prec(y)=98\n"); + printf ("expected "); mpfr_print_raw (x); putchar('\n'); + printf ("got "); mpfr_print_raw (z); putchar('\n'); + exit (1); + } + + mpfr_set_prec (x, 33); + mpfr_set_ui (x, 1, GMP_RNDN); + mpfr_div_2exp (x, x, 32, GMP_RNDN); + mpfr_sub_ui (x, x, 1, GMP_RNDN); + + mpfr_set_prec (x, 5); + mpfr_set_prec (y, 5); + mpfr_set_str_raw (x, "1e-12"); + mpfr_set_ui (y, 1, GMP_RNDN); + mpfr_sub (x, y, x, GMP_RNDD); + mpfr_set_str_raw (y, "0.11111"); + if (mpfr_cmp (x, y)) + { + fprintf (stderr, "Error in mpfr_sub (x, y, x, GMP_RNDD) for x=2^(-12), y=1\n"); + exit (1); + } + + mpfr_set_prec (x, 24); + mpfr_set_prec (y, 24); + mpfr_set_str_raw (x, "-0.100010000000000000000000E19"); + mpfr_set_str_raw (y, "0.100000000000000000000100E15"); + mpfr_add (x, x, y, GMP_RNDD); + mpfr_set_str_raw (y, "-0.1E19"); + if (mpfr_cmp (x, y)) + { + fprintf (stderr, "Error in mpfr_add (2)\n"); + exit (1); + } + + mpfr_set_prec (x, 1); + mpfr_set_prec (y, 10); + mpfr_set_prec (z, 10); + mpfr_set_ui (y, 0, GMP_RNDN); + mpfr_set_str_raw (z, "0.100000000000000000000100E15"); + if (mpfr_sub (x, y, z, GMP_RNDN) <= 0) + { + fprintf (stderr, "Wrong inexact flag in x=mpfr_sub(0,z) for prec(z)>prec(x)\n"); + exit (1); + } + if (mpfr_sub (x, z, y, GMP_RNDN) >= 0) + { + fprintf (stderr, "Wrong inexact flag in x=mpfr_sub(z,0) for prec(z)>prec(x)\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} + +void +bug_ddefour() +{ + mpfr_t ex, ex1, ex2, ex3, tot, tot1; + + mpfr_init2(ex, 53); + mpfr_init2(ex1, 53); + mpfr_init2(ex2, 53); + mpfr_init2(ex3, 53); + mpfr_init2(tot, 150); + mpfr_init2(tot1, 150); + + mpfr_set_ui( ex, 1, GMP_RNDN); + mpfr_mul_2exp( ex, ex, 906, GMP_RNDN); + mpfr_log( tot, ex, GMP_RNDN); + mpfr_set( ex1, tot, GMP_RNDN); /* ex1 = high(tot) */ + mpfr_sub( ex2, tot, ex1, GMP_RNDN); /* ex2 = high(tot - ex1) */ + mpfr_sub( tot1, tot, ex1, GMP_RNDN); /* tot1 = tot - ex1 */ + mpfr_set( ex3, tot1, GMP_RNDN); /* ex3 = high(tot - ex1) */ + + if (mpfr_cmp(ex2, ex3)) + { + fprintf (stderr, "Error in ddefour test.\n"); + printf ("ex2="); mpfr_print_raw (ex2); putchar ('\n'); + printf ("ex3="); mpfr_print_raw (ex3); putchar ('\n'); + exit (1); + } + + mpfr_clear (ex); + mpfr_clear (ex1); + mpfr_clear (ex2); + mpfr_clear (ex3); + mpfr_clear (tot); + mpfr_clear (tot1); +} + +/* if u = o(x-y), v = o(u-x), w = o(v+y), then x-y = u-w */ +void +check_two_sum (mp_prec_t p) +{ + mpfr_t x, y, u, v, w; + mp_rnd_t rnd; + int inexact; + + mpfr_init2 (x, p); + mpfr_init2 (y, p); + mpfr_init2 (u, p); + mpfr_init2 (v, p); + mpfr_init2 (w, p); + mpfr_random (x); + mpfr_random (y); + if (mpfr_cmp_abs (x, y) < 0) + mpfr_swap (x, y); + rnd = rand() % 4; + rnd = GMP_RNDN; + inexact = mpfr_sub (u, x, y, GMP_RNDN); + mpfr_sub (v, u, x, GMP_RNDN); + mpfr_add (w, v, y, GMP_RNDN); + /* as u = (x-y) - w, we should have inexact and w of opposite signs */ + if (((inexact == 0) && mpfr_cmp_ui (w, 0)) || + ((inexact > 0) && (mpfr_cmp_ui (w, 0) <= 0)) || + ((inexact < 0) && (mpfr_cmp_ui (w, 0) >= 0))) + { + fprintf (stderr, "Wrong inexact flag for prec=%u, rnd=%s\n", (unsigned)p, + mpfr_print_rnd_mode (rnd)); + printf ("x="); mpfr_print_raw(x); putchar('\n'); + printf ("y="); mpfr_print_raw(y); putchar('\n'); + printf ("u="); mpfr_print_raw(u); putchar('\n'); + printf ("v="); mpfr_print_raw(v); putchar('\n'); + printf ("w="); mpfr_print_raw(w); putchar('\n'); + printf ("inexact = %d\n", inexact); + exit (1); + } + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (u); + mpfr_clear (v); + mpfr_clear (w); +} + +#define MAX_PREC 100 + +void +check_inexact () +{ + mpfr_t x, y, z, u; + mp_prec_t px, py, pu, pz; + int inexact, cmp; + mp_rnd_t rnd; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + mpfr_init (u); + + for (px=1; px<MAX_PREC; px++) + { + mpfr_set_prec (x, px); + mpfr_random (x); + for (pu=1; pu<MAX_PREC; pu++) + { + mpfr_set_prec (u, pu); + mpfr_random (u); + for (py=1; py<MAX_PREC; py++) + { + mpfr_set_prec (y, py); + pz = (mpfr_cmp_abs (x, u) >= 0) ? MPFR_EXP(x)-MPFR_EXP(u) + : MPFR_EXP(u)-MPFR_EXP(x); + pz = pz + MAX(MPFR_PREC(x), MPFR_PREC(u)); + mpfr_set_prec (z, pz); + rnd = rand () % 4; + if (mpfr_sub (z, x, u, rnd)) + { + fprintf (stderr, "z <- x - u should be exact\n"); + exit (1); + } + for (rnd=0; rnd<4; rnd++) + { + inexact = mpfr_sub (y, x, u, rnd); + cmp = mpfr_cmp (y, z); + if (((inexact == 0) && (cmp != 0)) || + ((inexact > 0) && (cmp <= 0)) || + ((inexact < 0) && (cmp >= 0))) + { + fprintf (stderr, "Wrong inexact flag for rnd=%s\n", + mpfr_print_rnd_mode(rnd)); + printf ("expected %d, got %d\n", cmp, inexact); + printf ("x="); mpfr_print_raw (x); putchar ('\n'); + printf ("u="); mpfr_print_raw (u); putchar ('\n'); + printf ("y= "); mpfr_print_raw (y); putchar ('\n'); + printf ("x-u="); mpfr_print_raw (z); putchar ('\n'); + exit (1); + } + } + } + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); + mpfr_clear (u); +} + +int +main() +{ + mp_prec_t p; + unsigned i; + + check_diverse (); + check_inexact (); + bug_ddefour (); + + for (p=1; p<200; p++) + for (i=0; i<200; i++) + check_two_sum (p); + + return 0; +} diff --git a/mpfr/tests/tsub_ui.c b/mpfr/tests/tsub_ui.c new file mode 100644 index 000000000..296fb1b4c --- /dev/null +++ b/mpfr/tests/tsub_ui.c @@ -0,0 +1,152 @@ +/* Test file for mpfr_sub_ui + +Copyright (C) 2000-2001 Free Software Foundation. + +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 <math.h> +#include <stdio.h> +#include <stdlib.h> +#include "gmp.h" +#include "mpfr.h" +#include "mpfr-impl.h" +#ifdef __mips +#include <sys/fpu.h> +#endif + +void check_two_sum _PROTO ((mp_prec_t)); +void check3 _PROTO ((double, unsigned long, mp_rnd_t, double)); + +#define ABS(x) (((x)>0) ? (x) : (-x)) + +#define check(x,y,r) check3(x,y,r,0.0) + +/* checks that x+y gives the same results in double + and with mpfr with 53 bits of precision */ +void check3 (double x, unsigned long y, mp_rnd_t rnd_mode, double z1) +{ + double z2; + mpfr_t xx,zz; + + mpfr_init(xx); + mpfr_init(zz); + mpfr_set_prec(xx, 53); + mpfr_set_prec(zz, 53); + mpfr_set_d(xx, x, rnd_mode); + mpfr_sub_ui(zz, xx, y, rnd_mode); +#ifdef TEST + mpfr_set_machine_rnd_mode(rnd_mode); +#endif + if (z1==0.0) z1 = x-y; + z2 = mpfr_get_d(zz); + if (z1!=z2 && !(isnan(z1) && isnan(z2))) { + printf("expected sum is %1.20e, got %1.20e\n",z1,z2); + printf("mpfr_sub_ui failed for x=%1.20e y=%lu with rnd_mode=%s\n", + x, y, mpfr_print_rnd_mode(rnd_mode)); + exit(1); + } + mpfr_clear(xx); + mpfr_clear(zz); +} + +/* FastTwoSum: if EXP(x) >= EXP(y), u = o(x+y), v = o(u-x), w = o(y-v), + then x + y = u + w +thus if u = o(y-x), v = o(u+x), w = o(v-y), then y-x = u-w */ +void +check_two_sum (mp_prec_t p) +{ + unsigned int x; + mpfr_t y, u, v, w; + mp_rnd_t rnd; + int inexact; + + mpfr_init2 (y, p); + mpfr_init2 (u, p); + mpfr_init2 (v, p); + mpfr_init2 (w, p); + do + { + x = lrand48 (); + } + while (x < 1); + mpfr_random (y); + rnd = rand() % 4; + rnd = GMP_RNDN; + inexact = mpfr_sub_ui (u, y, x, GMP_RNDN); + mpfr_add_ui (v, u, x, GMP_RNDN); + mpfr_sub (w, v, y, GMP_RNDN); + /* as u - (y-x) = w, we should have inexact and w of same sign */ + if (((inexact == 0) && mpfr_cmp_ui (w, 0)) || + ((inexact > 0) && (mpfr_cmp_ui (w, 0) <= 0)) || + ((inexact < 0) && (mpfr_cmp_ui (w, 0) >= 0))) + { + fprintf (stderr, "Wrong inexact flag for prec=%u, rnd=%s\n", (unsigned)p, + mpfr_print_rnd_mode (rnd)); + printf ("x=%u\n", x); + printf ("y="); mpfr_print_raw(y); putchar('\n'); + printf ("u="); mpfr_print_raw(u); putchar('\n'); + printf ("v="); mpfr_print_raw(v); putchar('\n'); + printf ("w="); mpfr_print_raw(w); putchar('\n'); + printf ("inexact = %d\n", inexact); + exit (1); + } + mpfr_clear (y); + mpfr_clear (u); + mpfr_clear (v); + mpfr_clear (w); +} + +int main(argc,argv) int argc; char *argv[]; +{ + mp_prec_t p; + int k; +#ifdef __mips + /* to get denormalized numbers on IRIX64 */ + union fpc_csr exp; + exp.fc_word = get_fpc_csr(); + exp.fc_struct.flush = 0; + set_fpc_csr(exp.fc_word); +#endif +#ifdef TEST + double x; unsigned long y, N; int i,rnd_mode,rnd; + + srand(getpid()); + N = (argc<2) ? 1000000 : atoi(argv[1]); + rnd_mode = (argc<3) ? -1 : atoi(argv[2]); + for (i=0;i<1000000;i++) { + x = drand48(); + y = lrand48(); + if (ABS(x)>2.2e-307 && x+y<1.7e+308 && x+y>-1.7e308) { + /* avoid denormalized numbers and overflows */ + rnd = (rnd_mode==-1) ? lrand48()%4 : rnd_mode; + check(x, y, rnd); + } + } +#endif + + for (p=1; p<200; p++) + for (k=0; k<200; k++) + check_two_sum (p); + check3(0.9999999999, 1, GMP_RNDN, -1.000000082740370999e-10); + check3(0.0/0.0, 1, GMP_RNDN, 0.0/0.0); + check3(1.0/0.0, 1, GMP_RNDN, 1.0/0.0); + check3(-1.0/0.0, 1, GMP_RNDN, -1.0/0.0); + return 0; +} + + diff --git a/mpfr/tests/tswap.c b/mpfr/tests/tswap.c index 1cdbcd3ac..b397c9742 100644 --- a/mpfr/tests/tswap.c +++ b/mpfr/tests/tswap.c @@ -1,28 +1,31 @@ /* Test file for mpfr_swap. -Copyright (C) 2000 Free Software Foundation, Inc. +Copyright (C) 2000, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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 <stdio.h> +#include <stdlib.h> #include "gmp.h" #include "mpfr.h" -int main() +int +main (void) { mpfr_t u, v; @@ -38,5 +41,6 @@ int main() } mpfr_clear (u); mpfr_clear (v); + return 0; } diff --git a/mpfr/tests/ttan.c b/mpfr/tests/ttan.c new file mode 100644 index 000000000..b667505c0 --- /dev/null +++ b/mpfr/tests/ttan.c @@ -0,0 +1,75 @@ +/* Test file for mpfr_tan. + +Copyright (C) 2001 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 <stdio.h> +#include <stdlib.h> +#include <math.h> +#include "gmp.h" +#include "mpfr.h" + +void check53 _PROTO ((double, double, mp_rnd_t)); + +void check53 (double x, double tan_x, mp_rnd_t rnd_mode) +{ + mpfr_t xx, s; + + mpfr_init2 (xx, 53); + mpfr_init2 (s, 53); + mpfr_set_d (xx, x, rnd_mode); /* should be exact */ + mpfr_tan (s, xx, rnd_mode); + if (mpfr_get_d (s) != tan_x && (!isnan(tan_x) || !isnan(mpfr_get_d(s)))) { + fprintf (stderr, "mpfr_tan failed for x=%1.20e, rnd=%s\n", x, + mpfr_print_rnd_mode (rnd_mode)); + fprintf (stderr, "mpfr_tan gives tan(x)=%1.20e, expected %1.20e\n", + mpfr_get_d (s), tan_x); + exit(1); + } + mpfr_clear (xx); + mpfr_clear (s); +} + +#define TEST_FUNCTION mpfr_tan +#include "tgeneric.c" + +int +main(int argc, char *argv[]) +{ + mpfr_t x; + + check53(0.0/0.0, 0.0/0.0, GMP_RNDN); + check53(1.0/0.0, 0.0/0.0, GMP_RNDN); + check53(-1.0/0.0, 0.0/0.0, GMP_RNDN); + + mpfr_init (x); + mpfr_set_prec (x, 1); + mpfr_set_d (x, 0.5, GMP_RNDN); + mpfr_tan (x, x, GMP_RNDD); + if (mpfr_get_d(x) != 0.50) + { + fprintf (stderr, "mpfr_tan(0.5, GMP_RNDD) failed\n"); + exit (1); + } + mpfr_clear (x); + + test_generic (1, 100, 100); + + return 0; +} diff --git a/mpfr/tests/ttanh.c b/mpfr/tests/ttanh.c new file mode 100644 index 000000000..b83f0b689 --- /dev/null +++ b/mpfr/tests/ttanh.c @@ -0,0 +1,37 @@ +/* Test file for mpfr_tanh. + +Copyright (C) 2001 Free Software Foundation. +Adapted from tarctan.c. + +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 <stdio.h> +#include <stdlib.h> +#include <gmp.h> +#include <mpfr.h> + +#define TEST_FUNCTION mpfr_tanh +#include "tgeneric.c" + +int +main (int argc, char *argv[]) +{ + test_generic (1, 100, 100); + + return 0; +} diff --git a/mpfr/tests/ttrunc.c b/mpfr/tests/ttrunc.c index 41987170d..754dce02b 100644 --- a/mpfr/tests/ttrunc.c +++ b/mpfr/tests/ttrunc.c @@ -1,20 +1,20 @@ /* Test file for mpfr_trunc, mpfr_ceil, mpfr_floor. -Copyright (C) 1999-2000 Free Software Foundation. +Copyright (C) 1999, 2000, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ @@ -27,7 +27,8 @@ MA 02111-1307, USA. */ #define SIZEX 100 -int main() +int +main (void) { int j, k; mpfr_t x, y, z, t, y2, z2, t2; @@ -141,4 +142,3 @@ int main() return 0; } - diff --git a/mpfr/tests/tui_div.c b/mpfr/tests/tui_div.c index b3e812378..42b0f45b8 100644 --- a/mpfr/tests/tui_div.c +++ b/mpfr/tests/tui_div.c @@ -1,20 +1,20 @@ /* Test file for mpfr_ui_div. -Copyright (C) 2000 Free Software Foundation. +Copyright (C) 2000, 2001 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ @@ -29,6 +29,7 @@ MA 02111-1307, USA. */ #endif void check _PROTO((unsigned long, double, mp_rnd_t, double)); +void check_inexact _PROTO((void)); /* checks that y/x gives the same results in double and with mpfr with 53 bits of precision */ @@ -51,10 +52,64 @@ void check (unsigned long y, double x, mp_rnd_t rnd_mode, double z1) y, x, mpfr_print_rnd_mode(rnd_mode)); exit(1); } - mpfr_clear(xx); mpfr_clear(zz); + mpfr_clear(xx); + mpfr_clear(zz); } -int main(argc,argv) int argc; char *argv[]; +void +check_inexact () +{ + mpfr_t x, y, z; + mp_prec_t px, py; + int inexact, cmp; + unsigned long int u; + mp_rnd_t rnd; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (z); + + for (px=1; px<300; px++) + { + mpfr_set_prec (x, px); + mpfr_random (x); + u = lrand48 (); + for (py=1; py<300; py++) + { + mpfr_set_prec (y, py); + mpfr_set_prec (z, py + px); + for (rnd=0; rnd<4; rnd++) + { + inexact = mpfr_ui_div (y, u, x, rnd); + if (mpfr_mul (z, y, x, rnd)) + { + fprintf (stderr, "z <- y * x should be exact\n"); + exit (1); + } + cmp = mpfr_cmp_ui (z, u); + if (((inexact == 0) && (cmp != 0)) || + ((inexact > 0) && (cmp <= 0)) || + ((inexact < 0) && (cmp >= 0))) + { + fprintf (stderr, "Wrong inexact flag for u=%lu, rnd=%s\n", u, + mpfr_print_rnd_mode(rnd)); + printf ("expected %d, got %d\n", cmp, inexact); + printf ("x="); mpfr_print_raw (x); putchar ('\n'); + printf ("y="); mpfr_print_raw (y); putchar ('\n'); + printf ("y*x="); mpfr_print_raw (z); putchar ('\n'); + exit (1); + } + } + } + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} + +int +main (int argc, char *argv[]) { #ifdef TEST double x; unsigned long y, N; int i,rnd_mode,rnd; @@ -79,6 +134,7 @@ int main(argc,argv) int argc; char *argv[]; } } #endif + check_inexact (); check(1, 1.0/0.0, GMP_RNDN, 0.0); check(1, -1.0/0.0, GMP_RNDN, -0.0); check(1, 0.0/0.0, GMP_RNDN, 0.0/0.0); @@ -93,6 +149,6 @@ int main(argc,argv) int argc; char *argv[]; 1.3178666932321966062e285); check(1476599377, -2.14191393656148625995e+305, GMP_RNDD, -6.8938315017943889615e-297); + return 0; } - diff --git a/mpfr/tests/tui_pow.c b/mpfr/tests/tui_pow.c new file mode 100644 index 000000000..1822647ff --- /dev/null +++ b/mpfr/tests/tui_pow.c @@ -0,0 +1,149 @@ +/* Test file for mpfr_ui_pow. + +Copyright (C) 2001 Free Software Foundation. +Adapted from tarctan.c. + +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 <stdio.h> +#include <stdlib.h> +#include <gmp.h> +#include "gmp-impl.h" +#include <mpfr.h> +#include "mpfr-impl.h" + + +int +main (int argc, char *argv[]) +{ + mpfr_t x, y; + unsigned long int n; + + mpfr_init (x); + mpfr_init (y); + + n=abs(random()); + + MPFR_SET_INF(x); + mpfr_ui_pow (y, n,x, GMP_RNDN); + if(!MPFR_IS_INF(y)) + { + printf ("evaluation of function in INF does not return INF"); + exit (1); + } + + MPFR_CHANGE_SIGN(x); + mpfr_ui_pow (y, n,x, GMP_RNDN); + if(!MPFR_IS_ZERO(y)) + { + printf ("evaluation of function in -INF does not return 0"); + exit (1); + } + + MPFR_SET_NAN(x); + mpfr_ui_pow (y, n,x, GMP_RNDN); + if(!MPFR_IS_NAN(y)) + { + printf ("evaluation of function in NAN does not return NAN"); + exit (1); + } + + { + mp_prec_t prec, yprec; + mpfr_t z, t; + mp_rnd_t rnd; + int inexact, compare, compare2; + unsigned int n, err; + + int p0=1; + int p1=100; + int N=100; + + mpfr_init (z); + mpfr_init (t); + + /* generic test */ + for (prec = p0; prec <= p1; prec++) + { + mpfr_set_prec (x, prec); + mpfr_set_prec (z, prec); + mpfr_set_prec (t, prec); + yprec = prec + 10; + + for (n=0; n<N; n++) + { + int nt; + nt = abs(random()); + mpfr_random (x); + rnd = random () % 4; + mpfr_set_prec (y, yprec); + compare = mpfr_ui_pow (y, nt, x, rnd); + err = (rnd == GMP_RNDN) ? yprec + 1 : yprec; + if (mpfr_can_round (y, err, rnd, rnd, prec)) + { + mpfr_set (t, y, rnd); + inexact = mpfr_ui_pow (z, nt, x, rnd); + if (mpfr_cmp (t, z)) + { + printf ("results differ for x="); + mpfr_out_str (stdout, 2, prec, x, GMP_RNDN); + printf (" n= %i",nt); + printf (" prec=%u rnd_mode=%s\n", (unsigned) prec, + mpfr_print_rnd_mode (rnd)); + printf ("got "); + mpfr_out_str (stdout, 2, prec, z, GMP_RNDN); + putchar ('\n'); + printf ("expected "); + mpfr_out_str (stdout, 2, prec, t, GMP_RNDN); + putchar ('\n'); + printf ("approx "); + mpfr_print_raw (y); + putchar ('\n'); + exit (1); + } + compare2 = mpfr_cmp (t, y); + /* if rounding to nearest, cannot know the sign of t - f(x) + because of composed rounding: y = o(f(x)) and t = o(y) */ + if ((rnd != GMP_RNDN) && (compare * compare2 >= 0)) + compare = compare + compare2; + else + compare = inexact; /* cannot determine sign(t-f(x)) */ + if (((inexact == 0) && (compare != 0)) || + ((inexact > 0) && (compare <= 0)) || + ((inexact < 0) && (compare >= 0))) + { + fprintf (stderr, "Wrong inexact flag for rnd=%s: expected %d, got %d\n", + mpfr_print_rnd_mode (rnd), compare, inexact); + printf ("x="); mpfr_print_raw (x); putchar ('\n'); + printf ("y="); mpfr_print_raw (y); putchar ('\n'); + printf ("t="); mpfr_print_raw (t); putchar ('\n'); + exit (1); + } + } + } + } + + mpfr_clear (z); + mpfr_clear (t); + } + + mpfr_clear (x); + mpfr_clear (y); + + return 0; +} diff --git a/mpfr/tests/tui_sub.c b/mpfr/tests/tui_sub.c index 9456e7d10..6e8ccbdda 100644 --- a/mpfr/tests/tui_sub.c +++ b/mpfr/tests/tui_sub.c @@ -1,20 +1,20 @@ /* Test file for mpfr_ui_sub. -Copyright (C) 2000 Free Software Foundation. +Copyright (C) 2000-2001 Free Software Foundation. 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 Library General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at your +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 Library General Public +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 Library General Public License +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. */ @@ -28,11 +28,111 @@ MA 02111-1307, USA. */ #include "mpfr-test.h" #endif -void check _PROTO((unsigned long, double, mp_rnd_t, double)); +void special _PROTO ((void)); +void check _PROTO ((unsigned long, double, mp_rnd_t, double)); +void check_two_sum _PROTO ((mp_prec_t)); + +void +special () +{ + mpfr_t x, y, res; + int inexact; + + mpfr_init (x); + mpfr_init (y); + mpfr_init (res); + + mpfr_set_prec (x, 24); + mpfr_set_prec (y, 24); + mpfr_set_str_raw (y, "0.111100110001011010111"); + inexact = mpfr_ui_sub (x, 1, y, GMP_RNDN); + if (inexact) + { + fprintf (stderr, "Wrong inexact flag: got %d, expected 0\n", inexact); + exit (1); + } + + mpfr_set_prec (x, 24); + mpfr_set_prec (y, 24); + mpfr_set_str_raw (y, "0.111100110001011010111"); + if ((inexact = mpfr_ui_sub (x, 38181761, y, GMP_RNDN)) >= 0) + { + fprintf (stderr, "Wrong inexact flag: got %d, expected -1\n", inexact); + exit (1); + } + + mpfr_set_prec (x, 63); + mpfr_set_prec (y, 63); + mpfr_set_str_raw (y, "0.111110010010100100110101101010001001100101110001000101110111111E-1"); + if ((inexact = mpfr_ui_sub (x, 1541116494, y, GMP_RNDN)) <= 0) + { + fprintf (stderr, "Wrong inexact flag: got %d, expected +1\n", inexact); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + mpfr_set_str_raw (y, "0.11011000110111010001011100011100E-1"); + if ((inexact = mpfr_ui_sub (x, 2000375416, y, GMP_RNDN)) >= 0) + { + fprintf (stderr, "Wrong inexact flag: got %d, expected -1\n", inexact); + exit (1); + } + + mpfr_set_prec (x, 24); + mpfr_set_prec (y, 24); + mpfr_set_str_raw (y, "0.110011011001010011110111E-2"); + if ((inexact = mpfr_ui_sub (x, 927694848, y, GMP_RNDN)) <= 0) + { + fprintf (stderr, "Wrong inexact flag: got %d, expected +1\n", inexact); + exit (1); + } + + /* bug found by Mathieu Dutour, 12 Apr 2001 */ + mpfr_set_prec (x, 5); + mpfr_set_prec (y, 5); + mpfr_set_prec (res, 5); + mpfr_set_str_raw (x, "1e-12"); + + mpfr_ui_sub (y, 1, x, GMP_RNDD); + mpfr_set_str_raw (res, "0.11111"); + if (mpfr_cmp (y, res)) + { + fprintf (stderr, "Error in mpfr_ui_sub (y, 1, x, GMP_RNDD) for x=2^(-12)\nexpected 1.1111e-1, got "); + mpfr_out_str (stderr, 2, 0, y, GMP_RNDN); + fprintf (stderr, "\n"); + exit (1); + } + + mpfr_ui_sub (y, 1, x, GMP_RNDU); + mpfr_set_str_raw (res, "1.0"); + if (mpfr_cmp (y, res)) + { + fprintf (stderr, "Error in mpfr_ui_sub (y, 1, x, GMP_RNDU) for x=2^(-12)\nexpected 1.0, got "); + mpfr_out_str (stderr, 2, 0, y, GMP_RNDN); + fprintf (stderr, "\n"); + exit (1); + } + + mpfr_ui_sub (y, 1, x, GMP_RNDN); + mpfr_set_str_raw (res, "1.0"); + if (mpfr_cmp (y, res)) + { + fprintf (stderr, "Error in mpfr_ui_sub (y, 1, x, GMP_RNDN) for x=2^(-12)\nexpected 1.0, got "); + mpfr_out_str (stderr, 2, 0, y, GMP_RNDN); + fprintf (stderr, "\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (res); +} /* checks that y/x gives the same results in double and with mpfr with 53 bits of precision */ -void check (unsigned long y, double x, mp_rnd_t rnd_mode, double z1) +void +check (unsigned long y, double x, mp_rnd_t rnd_mode, double z1) { double z2; mpfr_t xx, zz; @@ -54,10 +154,60 @@ void check (unsigned long y, double x, mp_rnd_t rnd_mode, double z1) mpfr_clear(xx); mpfr_clear(zz); } -int main(argc,argv) int argc; char *argv[]; +/* if u = o(x-y), v = o(u-x), w = o(v+y), then x-y = u-w */ +void +check_two_sum (mp_prec_t p) +{ + unsigned int x; + mpfr_t y, u, v, w; + mp_rnd_t rnd; + int inexact; + + mpfr_init2 (y, p); + mpfr_init2 (u, p); + mpfr_init2 (v, p); + mpfr_init2 (w, p); + do + { + x = lrand48 (); + } + while (x < 1); + mpfr_random (y); + rnd = rand() % 4; + rnd = GMP_RNDN; + inexact = mpfr_ui_sub (u, x, y, GMP_RNDN); + mpfr_sub_ui (v, u, x, GMP_RNDN); + mpfr_add (w, v, y, GMP_RNDN); + /* as u = (x-y) + w, we should have inexact and w of same sign */ + if (((inexact == 0) && mpfr_cmp_ui (w, 0)) || + ((inexact > 0) && (mpfr_cmp_ui (w, 0) <= 0)) || + ((inexact < 0) && (mpfr_cmp_ui (w, 0) >= 0))) + { + fprintf (stderr, "Wrong inexact flag for prec=%u, rnd=%s\n", (unsigned)p, + mpfr_print_rnd_mode (rnd)); + printf ("x=%u\n", x); + printf ("y="); mpfr_print_raw(y); putchar('\n'); + printf ("u="); mpfr_print_raw(u); putchar('\n'); + printf ("v="); mpfr_print_raw(v); putchar('\n'); + printf ("w="); mpfr_print_raw(w); putchar('\n'); + printf ("inexact = %d\n", inexact); + exit (1); + } + mpfr_clear (y); + mpfr_clear (u); + mpfr_clear (v); + mpfr_clear (w); +} + +int +main (int argc, char *argv[]) { + mp_prec_t p; + unsigned k; #ifdef TEST - double x; unsigned long y, N; int i,rnd_mode,rnd; + double x; + unsigned long y, N; + int i, rnd_mode, rnd; #ifdef __mips /* to get denormalized numbers on IRIX64 */ union fpc_csr exp; @@ -79,6 +229,10 @@ int main(argc,argv) int argc; char *argv[]; } } #endif + special (); + for (p=1; p<100; p++) + for (k=0; k<100; k++) + check_two_sum (p); check(1, 1.0/0.0, GMP_RNDN, -1.0/0.0); check(1, -1.0/0.0, GMP_RNDN, 1.0/0.0); check(1, 0.0/0.0, GMP_RNDN, 0.0/0.0); @@ -94,6 +248,6 @@ int main(argc,argv) int argc; char *argv[]; 1.0849682612928422704e187); check(293607738, -1.9967571564050541e-5, GMP_RNDU, 2.9360773800002003e8); check(354270183, 2.9469161763489528e3, GMP_RNDN, 3.5426723608382362e8); + return 0; } - |