diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2017-05-29 12:27:01 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2017-05-29 12:27:01 +0000 |
commit | 4d76481f8f339d291ece5a3cf8a92e7819a86fc5 (patch) | |
tree | dcd13abf6a38a1f66a54faf61e7420804f334f72 | |
parent | af5a1593331d686b9cc5fbbbbdc47e1733a4644e (diff) | |
parent | 3a19337c08a0109b3d1554b0deb565bdb7eb0a9e (diff) | |
download | mpfr-4d76481f8f339d291ece5a3cf8a92e7819a86fc5.tar.gz |
Merged the latest changes from the trunk.
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/branches/faithful@11543 280ebfd0-de03-0410-8827-d642c229c3f4
51 files changed, 792 insertions, 490 deletions
@@ -452,6 +452,23 @@ For instance, under Unix, where paths are separated by a colon: setenv LIBRARY_PATH "/usr/local/lib:/other/path/lib" setenv LD_LIBRARY_PATH "$LIBRARY_PATH" +If almost all the tests fail and the messages in the test-suite.log file +(or in the output, when running individual tests from the command line) +start with a line of the form: + + Incorrect MPFR version! (xxx header vs yyy library) + +then this means that an installed MPFR version is tested instead of the +one that has just been built. This is probably not a bug in MPFR, but a +problem caused by the user or system configuration (particular options, +environment variables, etc.) or a bug in the toolchain. In particular, +if LD_LIBRARY_PATH overrides the run path (set up by libtool) and an +installed ABI-compatible version of MPFR is in a directory listed in +the LD_LIBRARY_PATH search path, then this will break. An example with +GNU ld: + + https://sourceware.org/bugzilla/show_bug.cgi?id=21476 + If you can't solve your problem, you should contact us via the MPFR mailing-list <mpfr@inria.fr>, indicating the machine and operating system used (uname -a), the compiler and version used (gcc -v if you use gcc), @@ -256,6 +256,7 @@ Table of contents: expression for the error in terms of the residual and the derivative W'(t), where the derivative can be bounded by piecewise simple functions, something like min(1, 1/t) when t >= 0. + See https://arxiv.org/abs/1705.03266 for rigorous error bounds. + Trigamma Function psi'(x). and Polygamma Function: psi^{(m)}(x) for m >= 0, x > 0. - functions from ISO/IEC 24747:2009 (Extensions to the C Library, diff --git a/acinclude.m4 b/acinclude.m4 index fc434e958..01e01e666 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -343,7 +343,7 @@ dnl Check the FP division by 0 fails (e.g. on a non-IEEE-754 platform). dnl In such a case, MPFR_ERRDIVZERO is defined to disable the tests dnl involving a FP division by 0. dnl For the developers: to check whether all these tests are disabled, -dnl configure MPFR with "-DMPFR_TESTS_DIVBYZERO -DMPFR_ERRDIVZERO". +dnl configure MPFR with "-DMPFR_TESTS_FPE_DIV -DMPFR_ERRDIVZERO". AC_CACHE_CHECK([if the FP division by 0 fails], mpfr_cv_errdivzero, [ AC_RUN_IFELSE([AC_LANG_SOURCE([[ int main (void) { diff --git a/doc/FAQ.html b/doc/FAQ.html index 5f9243491..f899c8fe2 100644 --- a/doc/FAQ.html +++ b/doc/FAQ.html @@ -337,19 +337,18 @@ installation using <cite>autoconf</cite> or <cite>pkg-config</cite>?</dt> <dd><p>The <cite><acronym>MPFR</acronym></cite> team does not currently recommend any <cite>autoconf</cite> code, but a section will later -be added to the <cite><acronym>MPFR</acronym></cite> manual. The -<cite><acronym>MPFR</acronym></cite> team does not wish to support -<cite>pkg-config</cite> yet.</p></dd> +be added to the <cite><acronym>MPFR</acronym></cite> manual. +Limited <cite>pkg-config</cite> support will be added for +<cite><acronym>MPFR</acronym></cite> 3.2.</p></dd> <dt id="cite">9. How to cite <cite><acronym>MPFR</acronym></cite> in a scientific publication?</dt> <dd><p>To properly cite <cite><acronym>MPFR</acronym></cite> in a scientific publication, please cite the -<a href="http://doi.acm.org/10.1145/1236463.1236468"><acronym title="Association for Computing Machinery">ACM</acronym> +<a href="https://doi.org/10.1145/1236463.1236468"><acronym title="Association for Computing Machinery">ACM</acronym> <acronym title="Transactions on Mathematical Software">TOMS</acronym> paper</a> -(<a href="http://toms.acm.org/cgi/TOMSbibget.cgi?Fousse:2007:MMP">BibTeX</a>) and/or the library web page <a href="http://www.mpfr.org/">http://www.mpfr.org</a>. If your publication is related to a particular release of <cite><acronym>MPFR</acronym></cite>, diff --git a/doc/README.dev b/doc/README.dev index 971020aa1..2b8987d80 100644 --- a/doc/README.dev +++ b/doc/README.dev @@ -244,9 +244,16 @@ To make a release (for the MPFR team): 32, mode32 and mode64 (in particular mode32, where long's have 32 bits and limbs have 64 bits [long long]). - Test with -DMPFR_TESTS_DIVBYZERO -DMPFR_ERRDIVZERO in order to detect - whether tests can fail due to a FP division by 0 on platforms where - such an operation fails (e.g. trap). + Test with -DMPFR_TESTS_FPE_DIV -DMPFR_ERRDIVZERO -DXDEBUG in order + to detect whether tests can fail due to a FP division by 0 (yielding + either FE_DIVBYZERO, e.g. from 1.0 / 0.0 to generate an infinity, or + FE_INVALID, e.g. from 0.0 / 0.0 to generate a NaN) on platforms where + such an operation fails (e.g. trap). On platforms that do not support + IEEE 754, such an operation yields an undefined behavior. + If _MPFR_IEEE_FLOATS is defined to 1 (by the configure script), some + divisions by 0 are avoided in the MPFR library. The -DXDEBUG option + sets _MPFR_IEEE_FLOATS to 0, allowing one to detect more issues, for + platforms without IEEE floats. Test with -D_MPFR_PREC_FORMAT=2 when the "int" type is smaller than the "long" type. @@ -466,12 +473,18 @@ List of macros used for checking MPFR: because it is regarded as undefined behavior by a sanitizer). This disables the tests involving such operations. -+ MPFR_TESTS_DIVBYZERO: Define to check whether there has been a - floating-point division by 0. This is normally ++ MPFR_TESTS_FPE_DIV: Define to check whether there has been a FP + exception FE_DIVBYZERO or FE_INVALID, which + probably comes from 1.0 / 0.0 or 0.0 / 0.0 to + generate an infinity or a NaN. This is normally used together with MPFR_ERRDIVZERO, in order to check that all divisions by 0 have been protected in the tests (so that tests can pass on platforms where the floating-point division by 0 fails). ++ MPFR_TESTS_FPE_TRAP: Define to trap the FE_DIVBYZERO and FE_INVALID + exceptions; MPFR_TESTS_FPE_DIV needs to be defined + too, and MPFR_ERRDIVZERO should be defined as well + to avoid spurious traps (see above). + MPFR_TESTS_TIMEOUT: Define to enable timeout in the tests. Its value contains the default timeout (in seconds), or 0 for no timeout by default, and can be overridden diff --git a/src/bernoulli.c b/src/bernoulli.c index 68e74903a..ba6344414 100644 --- a/src/bernoulli.c +++ b/src/bernoulli.c @@ -24,7 +24,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., /* assume p >= 5 and is odd */ static int -isprime (unsigned long p) +is_prime (unsigned long p) { unsigned long q; @@ -68,7 +68,7 @@ mpfr_bernoulli_internal (mpz_t *b, unsigned long n) mpz_init_set_ui (den, 6); for (p = 5; p <= n+1; p += 2) { - if ((n % (p-1)) == 0 && isprime (p)) + if ((n % (p-1)) == 0 && is_prime (p)) mpz_mul_ui (den, den, p); } if (n <= 64) diff --git a/src/cmp2.c b/src/cmp2.c index 14df57afd..7b58859c7 100644 --- a/src/cmp2.c +++ b/src/cmp2.c @@ -82,12 +82,14 @@ mpfr_cmp2 (mpfr_srcptr b, mpfr_srcptr c, mpfr_prec_t *cancel) if (MPFR_UNLIKELY (bn < 0)) { - if (MPFR_LIKELY (cn < 0)) /* b = c */ + if (MPFR_LIKELY (cn < 0)) /* |b| = |c| */ return 0; + /* b has been read entirely, but not c. Replace b by c for the + symmetric case below (only the sign differs if not 0). */ bp = cp; bn = cn; - cn = -1; + cn = -1; /* to enter the following "if" */ sign = -1; } @@ -100,7 +102,7 @@ mpfr_cmp2 (mpfr_srcptr b, mpfr_srcptr c, mpfr_prec_t *cancel) while (bp[bn] == 0) { - if (--bn < 0) /* b = c */ + if (--bn < 0) /* |b| = |c| */ return 0; res += GMP_NUMB_BITS; } @@ -145,7 +147,7 @@ mpfr_cmp2 (mpfr_srcptr b, mpfr_srcptr c, mpfr_prec_t *cancel) if (MPFR_LIKELY (diff_exp < GMP_NUMB_BITS)) { cc = cp[cn] >> diff_exp; - /* warning: a shift by GMP_NUMB_BITS may give wrong results */ + /* warning: a shift by GMP_NUMB_BITS is not allowed by ISO C */ if (diff_exp) lastc = cp[cn] << (GMP_NUMB_BITS - diff_exp); cn--; diff --git a/src/gamma.c b/src/gamma.c index d3ad0c516..2cebfee8e 100644 --- a/src/gamma.c +++ b/src/gamma.c @@ -286,9 +286,10 @@ mpfr_gamma (mpfr_ptr gamma, mpfr_srcptr x, mpfr_rnd_t rnd_mode) >= 2 * (x/e)^x / x for x >= 1 */ if (compared > 0) { - mpfr_t yp; + mpfr_t yp, zp; mpfr_exp_t expxp; MPFR_BLOCK_DECL (flags); + MPFR_GROUP_DECL (group); /* quick test for the default exponent range */ if (mpfr_get_emax () >= 1073741823UL && MPFR_GET_EXP(x) <= 25) @@ -297,22 +298,19 @@ mpfr_gamma (mpfr_ptr gamma, mpfr_srcptr x, mpfr_rnd_t rnd_mode) return mpfr_gamma_aux (gamma, x, rnd_mode); } + MPFR_GROUP_INIT_3 (group, 53, xp, yp, zp); /* 1/e rounded down to 53 bits */ -#define EXPM1_STR "0.010111100010110101011000110110001011001110111100111" - mpfr_init2 (xp, 53); - mpfr_init2 (yp, 53); - mpfr_set_str_binary (xp, EXPM1_STR); - mpfr_mul (xp, x, xp, MPFR_RNDZ); + mpfr_set_str_binary (zp, + "0.010111100010110101011000110110001011001110111100111"); + mpfr_mul (xp, x, zp, MPFR_RNDZ); mpfr_sub_ui (yp, x, 2, MPFR_RNDZ); mpfr_pow (xp, xp, yp, MPFR_RNDZ); /* (x/e)^(x-2) */ - mpfr_set_str_binary (yp, EXPM1_STR); - mpfr_mul (xp, xp, yp, MPFR_RNDZ); /* x^(x-2) / e^(x-1) */ - mpfr_mul (xp, xp, yp, MPFR_RNDZ); /* x^(x-2) / e^x */ + mpfr_mul (xp, xp, zp, MPFR_RNDZ); /* x^(x-2) / e^(x-1) */ + mpfr_mul (xp, xp, zp, MPFR_RNDZ); /* x^(x-2) / e^x */ mpfr_mul (xp, xp, x, MPFR_RNDZ); /* lower bound on x^(x-1) / e^x */ MPFR_BLOCK (flags, mpfr_mul_2ui (xp, xp, 1, MPFR_RNDZ)); expxp = MPFR_GET_EXP (xp); - mpfr_clear (xp); - mpfr_clear (yp); + MPFR_GROUP_CLEAR (group); MPFR_SAVE_EXPO_FREE (expo); return MPFR_OVERFLOW (flags) || expxp > __gmpfr_emax ? mpfr_overflow (gamma, rnd_mode, 1) : diff --git a/src/get_f.c b/src/get_f.c index 01ab0e2c2..ef5dec992 100644 --- a/src/get_f.c +++ b/src/get_f.c @@ -20,6 +20,7 @@ along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ +#define MPFR_NEED_MPF_INTERNALS #include "mpfr-impl.h" #ifndef MPFR_USE_MINI_GMP @@ -163,7 +163,7 @@ mpfr_jn (mpfr_ptr res, long n, mpfr_srcptr z, mpfr_rnd_t r) (res, z, -2 * MPFR_GET_EXP (z), 3, 0, r, { int inex2 = mpfr_div_2ui (res, res, 1, r); if (MPFR_UNLIKELY (r == MPFR_RNDN && MPFR_IS_ZERO (res)) && - (MPFR_ASSERTN (inex2 != 0), SIGN (_inexact) != MPFR_SIGN (z))) + (MPFR_ASSERTN (inex2 != 0), VSIGN (_inexact) != MPFR_SIGN (z))) { mpfr_nexttoinf (res); inex = - inex2; diff --git a/src/mpfr-gmp.h b/src/mpfr-gmp.h index a693df635..d25157adb 100644 --- a/src/mpfr-gmp.h +++ b/src/mpfr-gmp.h @@ -191,9 +191,16 @@ __MPFR_DECLSPEC void mpfr_assert_fail (const char *, int, #define SIZ(x) ((x)->_mp_size) #define ABSIZ(x) ABS (SIZ (x)) #define PTR(x) ((x)->_mp_d) +#define ALLOC(x) ((x)->_mp_alloc) +/* For mpf numbers only. */ +#ifdef MPFR_NEED_MPF_INTERNALS +/* Note: the EXP macro name is reserved when <errno.h> is included. + For compatibility with gmp-impl.h (cf --with-gmp-build), we cannot + change this macro, but let's define it only when we need it, where + <errno.h> will not be included. */ #define EXP(x) ((x)->_mp_exp) #define PREC(x) ((x)->_mp_prec) -#define ALLOC(x) ((x)->_mp_alloc) +#endif /* For longlong.h */ #ifdef HAVE_ATTRIBUTE_MODE diff --git a/src/mpfr-impl.h b/src/mpfr-impl.h index c241ae34e..69db32f4e 100644 --- a/src/mpfr-impl.h +++ b/src/mpfr-impl.h @@ -449,7 +449,9 @@ __MPFR_DECLSPEC extern const mpfr_t __gmpfr_const_log2_RNDU; MPFR_DBGRES(assignment): to be used when the result is tested only in an MPFR_ASSERTD expression (in order to avoid a warning, e.g. with GCC's -Wunused-but-set-variable, in non-debug mode). - */ + Note: Evaluating expr might yield side effects, but such side effects + must not change the results (except by yielding an assertion failure). +*/ #ifndef MPFR_WANT_ASSERT # define MPFR_WANT_ASSERT 0 #endif @@ -477,10 +479,18 @@ __MPFR_DECLSPEC extern const mpfr_t __gmpfr_const_log2_RNDU; __builtin_unreachable has been introduced in GCC 4.5 but it works fine since 4.8 only (before it may generate unoptimized code if there are more than one decision). - The use of __builtin_constant_p is to avoid calling any function in - assertions: it detects if the expression can be reduced to a constant, - i.e. if the expression has any other effect than being false or true - which is wrong if there is any function call. + Note: + The goal of MPFR_ASSUME() is to allow the compiler to optimize even + more. Thus we need to make sure that its use in MPFR will never yield + code generation. Since MPFR_ASSUME() may be used by MPFR_ASSERTN() + and MPFR_ASSERTD(), whose expression might have side effects, we need + to make sure that the expression x is not evaluated in such a case. + This is done with __builtin_constant_p (!!(x) || !(x)), whose value + is 0 if x has side effects, and normally 1 if the compiler knows that + x has no side effects (since here, it can deduce that !!(x) || !(x) + is equivalent to the constant 1). In the former case, MPFR_ASSUME(x) + will give (void) 0, and in the latter case, it will give: + (x) ? (void) 0 : __builtin_unreachable() In the development code, it is better to use MPFR_ASSERTD than MPFR_ASSUME, since it'll check if the condition is true in debug build. @@ -1002,8 +1012,9 @@ typedef uintmax_t mpfr_ueexp_t; (I) != 0 ? ((__gmpfr_flags |= MPFR_FLAGS_INEXACT), (I)) : 0 #define MPFR_RET_NAN return (__gmpfr_flags |= MPFR_FLAGS_NAN), 0 -#define SIGN(I) ((I) < 0 ? -1 : (I) > 0) -#define SAME_SIGN(I1,I2) (SIGN (I1) == SIGN (I2)) +/* Sign of a native value. */ +#define VSIGN(I) ((I) < 0 ? -1 : (I) > 0) +#define SAME_SIGN(I1,I2) (VSIGN (I1) == VSIGN (I2)) /****************************************************** diff --git a/src/mpfr-intmax.h b/src/mpfr-intmax.h index c982dd8ff..6cffccc54 100644 --- a/src/mpfr-intmax.h +++ b/src/mpfr-intmax.h @@ -47,9 +47,24 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., # include <inttypes.h> # define MPFR_USE_INTMAX_T #endif + #if HAVE_STDINT_H # include <stdint.h> # define MPFR_USE_INTMAX_T #endif +/* Largest signed integer type available for the MPFR build. */ +#if defined(MPFR_USE_INTMAX_T) +typedef intmax_t mpfr_intmax_t; +typedef uintmax_t mpfr_uintmax_t; +#elif defined(HAVE_LONG_LONG) +typedef long long mpfr_intmax_t; +typedef unsigned long long mpfr_uintmax_t; +# define MPFR_INTMAX_MAX LLONG_MAX +#else +typedef long mpfr_intmax_t; +typedef unsigned long mpfr_uintmax_t; +# define MPFR_INTMAX_MAX LONG_MAX +#endif + #endif diff --git a/src/printf.c b/src/printf.c index 4828b6365..65858d1a9 100644 --- a/src/printf.c +++ b/src/printf.c @@ -41,7 +41,6 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., # endif /* HAVE___VA_COPY */ #endif /* HAVE_VA_COPY */ -#include <errno.h> #include "mpfr-impl.h" #ifdef _MPFR_H_HAVE_FILE diff --git a/src/set_d.c b/src/set_d.c index d8a3091d2..a1f03534e 100644 --- a/src/set_d.c +++ b/src/set_d.c @@ -130,8 +130,16 @@ extract_double (mpfr_limb_ptr rp, double d) d *= MP_BASE_AS_DOUBLE; #if GMP_NUMB_BITS >= 64 +#ifndef __clang__ manl = d; #else + /* clang produces an invalid exception when d >= 2^63, + see https://bugs.llvm.org//show_bug.cgi?id=17686. + Since this is always the case, here, we use the following patch. */ + MPFR_STAT_STATIC_ASSERT (GMP_NUMB_BITS == 64); + manl = 0x8000000000000000 + (mp_limb_t) (d - 0x8000000000000000); +#endif /* __clang__ */ +#else MPFR_STAT_STATIC_ASSERT (GMP_NUMB_BITS == 32); manh = (mp_limb_t) d; manl = (mp_limb_t) ((d - manh) * MP_BASE_AS_DOUBLE); diff --git a/src/set_f.c b/src/set_f.c index 396ebe701..82b4e125b 100644 --- a/src/set_f.c +++ b/src/set_f.c @@ -21,6 +21,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #define MPFR_NEED_LONGLONG_H +#define MPFR_NEED_MPF_INTERNALS #include "mpfr-impl.h" #ifndef MPFR_USE_MINI_GMP diff --git a/src/vasprintf.c b/src/vasprintf.c index 0886567f5..04758f79c 100644 --- a/src/vasprintf.c +++ b/src/vasprintf.c @@ -71,6 +71,8 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., #include <stddef.h> /* for ptrdiff_t */ #endif +#include <errno.h> + #define MPFR_NEED_LONGLONG_H #include "mpfr-intmax.h" #include "mpfr-impl.h" @@ -505,16 +507,21 @@ typedef wint_t mpfr_va_wint; /* previous specifiers are understood by gmp_printf */ \ { \ MPFR_TMP_DECL (marker); \ - char *fmt_copy; \ + char *fmt_copy, *s; \ + int length; \ + \ MPFR_TMP_MARK (marker); \ fmt_copy = (char*) MPFR_TMP_ALLOC (n + 1); \ strncpy (fmt_copy, (start), n); \ fmt_copy[n] = '\0'; \ - if (sprntf_gmp ((buf_ptr), (fmt_copy), (ap)) == -1) \ + length = gmp_vasprintf (&s, fmt_copy, (ap)); \ + if (length < 0) \ { \ MPFR_TMP_FREE (marker); \ goto error; \ } \ + buffer_cat ((buf_ptr), s, length); \ + mpfr_free_str (s); \ (flag) = 0; \ MPFR_TMP_FREE (marker); \ } \ @@ -523,12 +530,14 @@ typedef wint_t mpfr_va_wint; buffer_cat ((buf_ptr), (start), n); \ } while (0) +/* Note: in case some form of %n is used in the format string, + we may need the maximum signed integer type for len. */ struct string_buffer { char *start; /* beginning of the buffer */ char *curr; /* null terminating character */ size_t size; /* buffer capacity */ - int len; /* string length or -1 if overflow */ + mpfr_intmax_t len; /* string length or -1 if overflow */ }; static void @@ -552,13 +561,19 @@ buffer_incr_len (struct string_buffer *b, size_t len) return 1; else { - size_t newlen = (size_t) b->len + len; + /* We need to take mpfr_uintmax_t as the type must be as large + as both size_t (which is unsigned) and mpfr_intmax_t (which + is used for the 'n' format specifier). */ + mpfr_uintmax_t newlen = (mpfr_uintmax_t) b->len + len; - /* size_t is unsigned, thus the above is valid, but one has - newlen < len in case of overflow. */ + /* mpfr_uintmax_t is unsigned, thus the above is valid, but one + has newlen < len in case of overflow. */ - if (MPFR_UNLIKELY (newlen < len || newlen > INT_MAX)) - return 1; + if (MPFR_UNLIKELY (newlen < len || newlen > MPFR_INTMAX_MAX)) + { + b->len = -1; + return 1; + } else { b->len = newlen; @@ -575,9 +590,10 @@ buffer_widen (struct string_buffer *b, size_t len) const size_t pos = b->curr - b->start; const size_t n = 0x1000 + (len & ~((size_t) 0xfff)); - /* An overflow is not possible since it would have been detected - in buffer_incr_len, called first (see buffer_* functions). */ - MPFR_ASSERTD (n >= 0x1000 && n >= len); + /* There are currently limitations here. We would need to switch to + the null-size behavior once there is an overflow in the buffer. */ + + MPFR_ASSERTN (n >= 0x1000 && n >= len); MPFR_ASSERTD (*b->curr == '\0'); MPFR_ASSERTD (pos < b->size); @@ -735,21 +751,6 @@ buffer_sandwich (struct string_buffer *b, char *str, size_t len, } } -/* let gmp_xprintf process the part it can understand */ -static int -sprntf_gmp (struct string_buffer *b, const char *fmt, va_list ap) -{ - int length; - char *s; - - length = gmp_vasprintf (&s, fmt, ap); - if (length > 0 && buffer_cat (b, s, length)) - length = -1; /* overflow in buffer_cat */ - - mpfr_free_str (s); - return length; -} - /* Helper struct and functions for temporary strings management */ /* struct for easy string clearing */ struct string_list @@ -1596,12 +1597,12 @@ regular_fg (struct number_parts *np, mpfr_srcptr p, return the total number of characters to be written. return -1 if an error occurred, in that case np's fields are in an undefined state but all string buffers have been freed. */ -static int +static mpfr_intmax_t partition_number (struct number_parts *np, mpfr_srcptr p, struct printf_spec spec) { char *str; - long total; + unsigned int total; /* can hold the sum of two non-negative int's + 1 */ int uppercase; /* WARNING: left justification means right space padding */ @@ -1818,43 +1819,43 @@ partition_number (struct number_parts *np, mpfr_srcptr p, /* compute the number of characters to be written verifying it is not too much */ + +#define INCR_TOTAL(v) \ + do { \ + MPFR_ASSERTD ((v) >= 0); \ + if (MPFR_UNLIKELY ((v) > MPFR_INTMAX_MAX)) \ + goto error; \ + total += (v); \ + if (MPFR_UNLIKELY (total > MPFR_INTMAX_MAX)) \ + goto error; \ + } while (0) + total = np->sign ? 1 : 0; - total += np->prefix_size; - total += np->ip_size; - if (MPFR_UNLIKELY (total < 0 || total > INT_MAX)) - goto error; - total += np->ip_trailing_zeros; - if (MPFR_UNLIKELY (total < 0 || total > INT_MAX)) - goto error; + INCR_TOTAL (np->prefix_size); + INCR_TOTAL (np->ip_size); + INCR_TOTAL (np->ip_trailing_zeros); + MPFR_ASSERTD (np->ip_size + np->ip_trailing_zeros >= 1); if (np->thousands_sep) /* ' flag, style f and the thousands separator in current locale is not reduced to the null character */ - total += (np->ip_size + np->ip_trailing_zeros) / 3; - if (MPFR_UNLIKELY (total < 0 || total > INT_MAX)) - goto error; + INCR_TOTAL ((np->ip_size + np->ip_trailing_zeros - 1) / 3); if (np->point) ++total; - total += np->fp_leading_zeros; - if (MPFR_UNLIKELY (total < 0 || total > INT_MAX)) - goto error; - total += np->fp_size; - if (MPFR_UNLIKELY (total < 0 || total > INT_MAX)) - goto error; - total += np->fp_trailing_zeros; - if (MPFR_UNLIKELY (total < 0 || total > INT_MAX)) - goto error; - total += np->exp_size; - if (MPFR_UNLIKELY (total < 0 || total > INT_MAX)) - goto error; + INCR_TOTAL (np->fp_leading_zeros); + INCR_TOTAL (np->fp_size); + INCR_TOTAL (np->fp_trailing_zeros); + INCR_TOTAL (np->exp_size); if (spec.width > total) /* pad with spaces or zeros depending on np->pad_type */ { np->pad_size = spec.width - total; total += np->pad_size; /* here total == spec.width, - so 0 < total < INT_MAX */ + so 0 < total <= INT_MAX */ + MPFR_ASSERTD (total == spec.width); } + MPFR_ASSERTD (total > 0 && total <= MPFR_INTMAX_MAX); return total; error: @@ -1870,7 +1871,7 @@ partition_number (struct number_parts *np, mpfr_srcptr p, return the size of the string (not counting the terminating '\0') return -1 if the built string is too long (i.e. has more than - INT_MAX characters). + INT_MAX or MPFR_INTMAX_MAX characters). If spec.size is 0, we only want the size of the string. */ @@ -1878,12 +1879,15 @@ static int sprnt_fp (struct string_buffer *buf, mpfr_srcptr p, const struct printf_spec spec) { - int length; + mpfr_intmax_t length, start; struct number_parts np; length = partition_number (&np, p, spec); if (length < 0) - return -1; + { + buf->len = -1; + return -1; + } if (spec.size == 0) { @@ -1893,6 +1897,8 @@ sprnt_fp (struct string_buffer *buf, mpfr_srcptr p, goto clear_and_exit; } + MPFR_DBGRES (start = buf->len); + /* right justification padding with left spaces */ if (np.pad_type == LEFT && np.pad_size != 0) buffer_pad (buf, ' ', np.pad_size); @@ -1947,6 +1953,8 @@ sprnt_fp (struct string_buffer *buf, mpfr_srcptr p, if (np.pad_type == RIGHT && np.pad_size != 0) buffer_pad (buf, ' ', np.pad_size); + MPFR_ASSERTD (buf->len == -1 || buf->len - start == length); + clear_and_exit: clear_string_list (np.sl); return buf->len == -1 ? -1 : length; @@ -1963,7 +1971,7 @@ mpfr_vasnprintf_aux (char **ptr, char *Buf, size_t size, const char *fmt, va_list ap) { struct string_buffer buf; - size_t nbchar; + int nbchar; /* informations on the conversion specification filled by the parser */ struct printf_spec spec; @@ -2089,49 +2097,47 @@ mpfr_vasnprintf_aux (char **ptr, char *Buf, size_t size, const char *fmt, so as to be able to accept the same format strings. */ { void *p; - size_t nchar; p = va_arg (ap, void *); FLUSH (xgmp_fmt_flag, start, end, ap2, &buf); va_end (ap2); start = fmt; - nchar = buf.curr - buf.start; switch (spec.arg_type) { case CHAR_ARG: - *(char *) p = (char) nchar; + *(char *) p = (char) buf.len; break; case SHORT_ARG: - *(short *) p = (short) nchar; + *(short *) p = (short) buf.len; break; case LONG_ARG: - *(long *) p = (long) nchar; + *(long *) p = (long) buf.len; break; #ifdef HAVE_LONG_LONG case LONG_LONG_ARG: - *(long long *) p = (long long) nchar; + *(long long *) p = (long long) buf.len; break; #endif #ifdef _MPFR_H_HAVE_INTMAX_T case INTMAX_ARG: - *(intmax_t *) p = (intmax_t) nchar; + *(intmax_t *) p = (intmax_t) buf.len; break; #endif case SIZE_ARG: - *(size_t *) p = nchar; + *(size_t *) p = buf.len; break; case PTRDIFF_ARG: - *(ptrdiff_t *) p = (ptrdiff_t) nchar; + *(ptrdiff_t *) p = (ptrdiff_t) buf.len; break; case MPF_ARG: - mpf_set_ui ((mpf_ptr) p, (unsigned long) nchar); + mpf_set_ui ((mpf_ptr) p, (unsigned long) buf.len); break; case MPQ_ARG: - mpq_set_ui ((mpq_ptr) p, (unsigned long) nchar, 1L); + mpq_set_ui ((mpq_ptr) p, (unsigned long) buf.len, 1L); break; case MP_LIMB_ARG: - *(mp_limb_t *) p = (mp_limb_t) nchar; + *(mp_limb_t *) p = (mp_limb_t) buf.len; break; case MP_LIMB_ARRAY_ARG: { @@ -2144,7 +2150,7 @@ mpfr_vasnprintf_aux (char **ptr, char *Buf, size_t size, const char *fmt, break; /* we assume here that mp_limb_t is wider than int */ - *q = (mp_limb_t) nchar; + *q = (mp_limb_t) buf.len; while (--n != 0) { q++; @@ -2153,16 +2159,16 @@ mpfr_vasnprintf_aux (char **ptr, char *Buf, size_t size, const char *fmt, } break; case MPZ_ARG: - mpz_set_ui ((mpz_ptr) p, (unsigned long) nchar); + mpz_set_ui ((mpz_ptr) p, (unsigned long) buf.len); break; case MPFR_ARG: - mpfr_set_ui ((mpfr_ptr) p, (unsigned long) nchar, + mpfr_set_ui ((mpfr_ptr) p, (unsigned long) buf.len, spec.rnd_mode); break; default: - *(int *) p = (int) nchar; + *(int *) p = (int) buf.len; } va_copy (ap2, ap); /* after the switch, due to MP_LIMB_ARRAY_ARG case */ @@ -2174,7 +2180,6 @@ mpfr_vasnprintf_aux (char **ptr, char *Buf, size_t size, const char *fmt, char format[MPFR_PREC_FORMAT_SIZE + 6]; /* see examples below */ size_t length; mpfr_prec_t prec; - int err; prec = va_arg (ap, mpfr_prec_t); @@ -2194,10 +2199,8 @@ mpfr_vasnprintf_aux (char **ptr, char *Buf, size_t size, const char *fmt, format[5 + MPFR_PREC_FORMAT_SIZE] = '\0'; length = gmp_asprintf (&s, format, spec.width, spec.prec, prec); MPFR_ASSERTN (length >= 0); /* guaranteed by GMP 6 */ - err = buffer_cat (&buf, s, length); + buffer_cat (&buf, s, length); mpfr_free_str (s); - if (err) - goto overflow_error; } else if (spec.arg_type == MPFR_ARG) /* output a mpfr_t variable */ @@ -2223,8 +2226,7 @@ mpfr_vasnprintf_aux (char **ptr, char *Buf, size_t size, const char *fmt, if (ptr == NULL) spec.size = size; - if (sprnt_fp (&buf, p, spec) < 0) - goto overflow_error; + sprnt_fp (&buf, p, spec); } else /* gmp_printf specification, step forward in the va_list */ @@ -2238,42 +2240,52 @@ mpfr_vasnprintf_aux (char **ptr, char *Buf, size_t size, const char *fmt, FLUSH (xgmp_fmt_flag, start, fmt, ap2, &buf); va_end (ap2); - MPFR_ASSERTD (buf.len >= 0); /* overflow already detected */ - nbchar = buf.len; - if (ptr != NULL) /* implement mpfr_vasprintf */ - { - MPFR_ASSERTD (nbchar == strlen (buf.start)); - *ptr = (char *) - (*__gmp_reallocate_func) (buf.start, buf.size, nbchar + 1); - } - else if (size > 0) /* implement mpfr_vsnprintf */ + if (buf.len > INT_MAX) /* overflow */ + buf.len = -1; + + if (buf.len != -1) { - if (nbchar < size) + nbchar = buf.len; + + if (ptr != NULL) /* implement mpfr_vasprintf */ { - strncpy (Buf, buf.start, nbchar); - Buf[nbchar] = '\0'; + MPFR_ASSERTD (nbchar == strlen (buf.start)); + *ptr = (char *) + (*__gmp_reallocate_func) (buf.start, buf.size, nbchar + 1); } - else + else if (size > 0) /* implement mpfr_vsnprintf */ { - strncpy (Buf, buf.start, size - 1); - Buf[size-1] = '\0'; + if (nbchar < size) + { + strncpy (Buf, buf.start, nbchar); + Buf[nbchar] = '\0'; + } + else + { + strncpy (Buf, buf.start, size - 1); + Buf[size-1] = '\0'; + } + (*__gmp_free_func) (buf.start, buf.size); } - (*__gmp_free_func) (buf.start, buf.size); - } - MPFR_SAVE_EXPO_FREE (expo); - return nbchar; /* return the number of characters that would have been - written had 'size' be sufficiently large, not counting - the terminating null character */ + MPFR_SAVE_EXPO_FREE (expo); + return nbchar; /* return the number of characters that would have + been written had 'size' be sufficiently large, + not counting the terminating null character */ + } - overflow_error: - MPFR_SAVE_EXPO_UPDATE_FLAGS(expo, MPFR_FLAGS_ERANGE); + error: + if (buf.len == -1) /* overflow */ + { + MPFR_LOG_MSG (("Overflow\n", 0)); + MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_ERANGE); #ifdef EOVERFLOW - errno = EOVERFLOW; + MPFR_LOG_MSG (("Setting errno to EOVERFLOW\n", 0)); + errno = EOVERFLOW; #endif + } - error: MPFR_SAVE_EXPO_FREE (expo); *ptr = NULL; (*__gmp_free_func) (buf.start, buf.size); diff --git a/src/zeta.c b/src/zeta.c index 950ab718f..21f05b017 100644 --- a/src/zeta.c +++ b/src/zeta.c @@ -424,7 +424,6 @@ int mpfr_zeta (mpfr_t z, mpfr_srcptr s, mpfr_rnd_t rnd_mode) { mpfr_t z_pre, s1, y, p; - double sd, eps, m1, c; long add; mpfr_prec_t precz, prec1, precs, precs1; int inex; @@ -534,32 +533,9 @@ mpfr_zeta (mpfr_t z, mpfr_srcptr s, mpfr_rnd_t rnd_mode) /* Precision precs1 needed to represent 1 - s, and s + 2, without any truncation */ precs1 = precs + 2 + MAX (0, - MPFR_GET_EXP (s)); - /* FIXME: For the error analysis, use MPFR instead of the native - double type. The code below can yield overflows on double's - when s is large enough (its precision also needs to be large - enough, otherwise s is an even integer, which has already been - taken into account). In particular, on platforms where overflow - is trapped (or if the user has chosen to trap overflow), this - can make the application crash. - Moreover, does the error computation need to be accurate, such as - the multiplications by (1.0 + eps)? If yes, what about rounding - directions when using double? If no, the expression could probably - be simplified, so that using native integer arithmetic with - mpfr_exp_t may be sufficient instead of using MPFR. - Note: This FIXME can be made obsolete by rewriting the code - (see algorithms.tex, still very incomplete). */ - sd = mpfr_get_d (s, MPFR_RNDN) - 1.0; - if (sd < 0.0) - sd = -sd; /* now sd = abs(s-1.0) */ /* Precision prec1 is the precision on elementary computations; it ensures a final precision prec1 - add for zeta(s) */ - /* eps = pow (2.0, - (double) precz - 14.0); */ - eps = __gmpfr_ceil_exp2 (- (double) precz - 14.0); - m1 = 1.0 + MAX(1.0 / eps, 2.0 * sd) * (1.0 + eps); - c = (1.0 + eps) * (1.0 + eps * MAX(8.0, m1)); - /* add = 1 + floor(log(c*c*c*(13 + m1))/log(2)); */ - c = c * c * c * (13.0 + m1); - add = (c <= DBL_MAX) ? __gmpfr_ceil_log2 (c) : compute_add (s, precz); + add = compute_add (s, precz); prec1 = precz + add; /* FIXME: To avoid that the working precision (prec1) depends on the input precision, one would need to take into account the error made diff --git a/tests/mpfr-test.h b/tests/mpfr-test.h index 689400900..2218cf52b 100644 --- a/tests/mpfr-test.h +++ b/tests/mpfr-test.h @@ -55,7 +55,7 @@ extern "C" { #define RND_RAND_NO_RNDF() ((mpfr_rnd_t) (randlimb() % MPFR_RNDF)) /* Generates a random sign */ -#define SIGN_RAND() ( (randlimb()%2) ? MPFR_SIGN_POS : MPFR_SIGN_NEG) +#define RAND_SIGN() (randlimb() % 2 ? MPFR_SIGN_POS : MPFR_SIGN_NEG) /* Loop for all rounding modes */ #define RND_LOOP(_r) for((_r) = 0 ; (_r) < MPFR_RND_MAX ; (_r)++) diff --git a/tests/tabs.c b/tests/tabs.c index 15a16cab3..b07d9e19e 100644 --- a/tests/tabs.c +++ b/tests/tabs.c @@ -135,7 +135,7 @@ check_cmp (int argc, char *argv[]) for (k = 1; k <= n; k++) { mpfr_rnd_t rnd; - int sign = SIGN_RAND (); + int sign = RAND_SIGN (); mpfr_urandomb (x, RANDS); MPFR_SET_SIGN (x, sign); diff --git a/tests/tagm.c b/tests/tagm.c index 2b87e3905..b364713b4 100644 --- a/tests/tagm.c +++ b/tests/tagm.c @@ -78,7 +78,7 @@ check4 (const char *as, const char *bs, mpfr_rnd_t rnd_mode, newflags = __gmpfr_flags; expflags |= MPFR_FLAGS_INEXACT; - if (SIGN (inex2) != inex || newflags != expflags || + if (VSIGN (inex2) != inex || newflags != expflags || ! mpfr_equal_p (tres, tc)) { printf ("mpfr_agm failed in rnd_mode=%s for\n", diff --git a/tests/tasin.c b/tests/tasin.c index 1f5a4dc89..efaf0bf87 100644 --- a/tests/tasin.c +++ b/tests/tasin.c @@ -242,7 +242,7 @@ reduced_expo_range (void) ex_inex = -1; ex_flags = MPFR_FLAGS_INEXACT; - if (SIGN (inex) != ex_inex || flags != ex_flags || + if (VSIGN (inex) != ex_inex || flags != ex_flags || ! mpfr_equal_p (y, ex_y)) { printf ("Error in reduced_expo_range\non x = "); @@ -252,7 +252,7 @@ reduced_expo_range (void) printf ("\n inex = %d, flags = %u\n", ex_inex, ex_flags); printf ("Got y = "); mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); - printf ("\n inex = %d, flags = %u\n", SIGN (inex), flags); + printf ("\n inex = %d, flags = %u\n", VSIGN (inex), flags); exit (1); } diff --git a/tests/tatan.c b/tests/tatan.c index ef38d0fe5..347aa1608 100644 --- a/tests/tatan.c +++ b/tests/tatan.c @@ -597,7 +597,7 @@ reduced_expo_range (void) ex_inex = 1; ex_flags = MPFR_FLAGS_INEXACT; - if (SIGN (inex) != ex_inex || flags != ex_flags || + if (VSIGN (inex) != ex_inex || flags != ex_flags || ! mpfr_equal_p (y, ex_y)) { printf ("Error in reduced_expo_range\non x = "); @@ -607,7 +607,7 @@ reduced_expo_range (void) printf ("\n inex = %d, flags = %u\n", ex_inex, ex_flags); printf ("Got y = "); mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); - printf ("\n inex = %d, flags = %u\n", SIGN (inex), flags); + printf ("\n inex = %d, flags = %u\n", VSIGN (inex), flags); exit (1); } diff --git a/tests/tcheck.c b/tests/tcheck.c index ef9d848b5..a6c17a935 100644 --- a/tests/tcheck.c +++ b/tests/tcheck.c @@ -22,7 +22,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., #include "mpfr-test.h" -#define ERROR(s) \ +#define PRINT_ERROR(s) \ (printf ("mpfr_check failed " s " Prec=%lu\n", (unsigned long) pr), \ exit(1)) @@ -36,88 +36,108 @@ main (void) int max; tests_start_mpfr (); - for(pr = MPFR_PREC_MIN ; pr < 500 ; pr++) + for (pr = MPFR_PREC_MIN ; pr < 500 ; pr++) { mpfr_init2 (a, pr); - if (!mpfr_check(a)) ERROR("for init"); + if (!mpfr_check (a)) + PRINT_ERROR ("for init"); /* Check special cases */ - MPFR_SET_NAN(a); - if (!mpfr_check(a)) ERROR("for nan"); - MPFR_SET_POS(a); - MPFR_SET_INF(a); - if (!mpfr_check(a)) ERROR("for inf"); - MPFR_SET_ZERO(a); - if (!mpfr_check(a)) ERROR("for zero"); + MPFR_SET_NAN (a); + if (!mpfr_check (a)) + PRINT_ERROR ("for nan"); + MPFR_SET_POS (a); + MPFR_SET_INF (a); + if (!mpfr_check (a)) + PRINT_ERROR ("for inf"); + MPFR_SET_ZERO (a); + if (!mpfr_check (a)) + PRINT_ERROR ("for zero"); MPFR_EXP (a) = MPFR_EXP_MIN; - if (mpfr_check(a)) ERROR("for EXP = MPFR_EXP_MIN"); + if (mpfr_check (a)) + PRINT_ERROR ("for EXP = MPFR_EXP_MIN"); /* Check var */ - mpfr_set_ui(a, 2, MPFR_RNDN); - if (!mpfr_check(a)) ERROR("for set_ui"); - mpfr_clear_overflow(); + mpfr_set_ui (a, 2, MPFR_RNDN); + if (!mpfr_check (a)) + PRINT_ERROR ("for set_ui"); + mpfr_clear_overflow (); max = 1000; /* Allows max 2^1000 bits for the exponent */ - while ((!mpfr_overflow_p()) && (max>0)) + while (!mpfr_overflow_p () && max > 0) { - mpfr_mul(a, a, a, MPFR_RNDN); - if (!mpfr_check(a)) ERROR("for mul"); + mpfr_mul (a, a, a, MPFR_RNDN); + if (!mpfr_check (a)) + PRINT_ERROR ("for mul"); max--; } - if (max==0) ERROR("can't reach overflow"); - mpfr_set_ui(a, 2137, MPFR_RNDN); + if (max == 0) + PRINT_ERROR ("can't reach overflow"); + mpfr_set_ui (a, 2137, MPFR_RNDN); /* Corrupt a and check for it */ - MPFR_SIGN(a) = 2; - if (mpfr_check(a)) ERROR("sgn"); - MPFR_SET_POS(a); + MPFR_SIGN (a) = 2; + if (mpfr_check (a)) + PRINT_ERROR ("sgn"); + MPFR_SET_POS (a); /* Check prec */ - MPFR_PREC(a) = MPFR_PREC_MIN - 1; - if (mpfr_check(a)) ERROR("precmin"); + MPFR_PREC (a) = MPFR_PREC_MIN - 1; + if (mpfr_check (a)) PRINT_ERROR ("precmin"); #if MPFR_VERSION_MAJOR < 3 /* Disable the test with MPFR >= 3 since mpfr_prec_t is now signed. The "if" below is sufficient, but the MPFR_PREC_MAX+1 generates a warning with GCC 4.4.4 even though the test is always false. */ if ((mpfr_prec_t) 0 - 1 > 0) { - MPFR_PREC(a) = MPFR_PREC_MAX+1; - if (mpfr_check(a)) ERROR("precmax"); + MPFR_PREC (a) = MPFR_PREC_MAX + 1; + if (mpfr_check (a)) + PRINT_ERROR ("precmax"); } #endif - MPFR_PREC(a) = pr; - if (!mpfr_check(a)) ERROR("prec"); + MPFR_PREC (a) = pr; + if (!mpfr_check (a)) + PRINT_ERROR ("prec"); /* Check exponent */ - MPFR_EXP(a) = MPFR_EXP_INVALID; - if (mpfr_check(a)) ERROR("exp invalid"); - MPFR_EXP(a) = -MPFR_EXP_INVALID; - if (mpfr_check(a)) ERROR("-exp invalid"); + MPFR_EXP (a) = MPFR_EXP_INVALID; + if (mpfr_check(a)) + PRINT_ERROR ("exp invalid"); + MPFR_EXP (a) = -MPFR_EXP_INVALID; + if (mpfr_check(a)) + PRINT_ERROR ("-exp invalid"); MPFR_EXP(a) = 0; - if (!mpfr_check(a)) ERROR("exp 0"); + if (!mpfr_check(a)) PRINT_ERROR ("exp 0"); /* Check Mantissa */ p = MPFR_MANT(a); - MPFR_MANT(a) = NULL; - if (mpfr_check(a)) ERROR("Mantissa Null Ptr"); - MPFR_MANT(a) = p; + MPFR_MANT (a) = NULL; + if (mpfr_check (a)) + PRINT_ERROR ("Mantissa Null Ptr"); + MPFR_MANT (a) = p; /* Check size */ - s = MPFR_GET_ALLOC_SIZE(a); - MPFR_SET_ALLOC_SIZE(a, 0); - if (mpfr_check(a)) ERROR("0 size"); - MPFR_SET_ALLOC_SIZE(a, MP_SIZE_T_MIN); - if (mpfr_check(a)) ERROR("min size"); - MPFR_SET_ALLOC_SIZE(a, MPFR_LIMB_SIZE(a)-1 ); - if (mpfr_check(a)) ERROR("size < prec"); - MPFR_SET_ALLOC_SIZE(a, s); + s = MPFR_GET_ALLOC_SIZE (a); + MPFR_SET_ALLOC_SIZE (a, 0); + if (mpfr_check (a)) + PRINT_ERROR ("0 size"); + MPFR_SET_ALLOC_SIZE (a, MP_SIZE_T_MIN); + if (mpfr_check (a)) PRINT_ERROR ("min size"); + MPFR_SET_ALLOC_SIZE (a, MPFR_LIMB_SIZE (a) - 1); + if (mpfr_check (a)) + PRINT_ERROR ("size < prec"); + MPFR_SET_ALLOC_SIZE (a, s); /* Check normal form */ - tmp = MPFR_MANT(a)[0]; + tmp = MPFR_MANT (a)[0]; if ((pr % GMP_NUMB_BITS) != 0) { MPFR_MANT(a)[0] = MPFR_LIMB_MAX; - if (mpfr_check(a)) ERROR("last bits non 0"); + if (mpfr_check (a)) + PRINT_ERROR ("last bits non 0"); } MPFR_MANT(a)[0] = tmp; MPFR_MANT(a)[MPFR_LIMB_SIZE(a)-1] &= MPFR_LIMB_MASK (GMP_NUMB_BITS-1); - if (mpfr_check(a)) ERROR("last bits non 0"); + if (mpfr_check (a)) + PRINT_ERROR ("last bits non 0"); /* Final */ - mpfr_set_ui(a, 2137, MPFR_RNDN); - if (!mpfr_check(a)) ERROR("after last set"); + mpfr_set_ui (a, 2137, MPFR_RNDN); + if (!mpfr_check (a)) + PRINT_ERROR ("after last set"); mpfr_clear (a); - if (mpfr_check(a)) ERROR("after clear"); + if (mpfr_check (a)) + PRINT_ERROR ("after clear"); } tests_end_mpfr (); return 0; diff --git a/tests/tcmp2.c b/tests/tcmp2.c index 901b63f82..1361e1393 100644 --- a/tests/tcmp2.c +++ b/tests/tcmp2.c @@ -299,6 +299,51 @@ special (void) mpfr_clear (y); } +/* Compare (m,kx) and (m,ky), where (m,k) means m fixed limbs followed by + k zero limbs. */ +static void +test_equal (void) +{ + mpfr_t w, x, y; + int m, kx, ky, inex; + mpfr_prec_t j; + + for (m = 1; m <= 4; m++) + { + mpfr_init2 (w, m * GMP_NUMB_BITS); + for (kx = 0; kx <= 4; kx++) + for (ky = 0; ky <= 4; ky++) + { + do mpfr_urandomb (w, RANDS); while (mpfr_zero_p (w)); + mpfr_init2 (x, (m + kx) * GMP_NUMB_BITS + - (kx == 0 ? 0 : randlimb () % GMP_NUMB_BITS)); + mpfr_init2 (y, (m + ky) * GMP_NUMB_BITS + - (ky == 0 ? 0 : randlimb () % GMP_NUMB_BITS)); + inex = mpfr_set (x, w, MPFR_RNDN); + MPFR_ASSERTN (inex == 0); + inex = mpfr_set (y, w, MPFR_RNDN); + MPFR_ASSERTN (inex == 0); + MPFR_ASSERTN (mpfr_equal_p (x, y)); + if (randlimb () & 1) + mpfr_neg (x, x, MPFR_RNDN); + if (randlimb () & 1) + mpfr_neg (y, y, MPFR_RNDN); + if (mpfr_cmp2 (x, y, &j) != 0) + { + printf ("Error in test_equal for m = %d, kx = %d, ky = %d\n", + m, kx, ky); + printf (" x = "); + mpfr_dump (x); + printf (" y = "); + mpfr_dump (y); + exit (1); + } + mpfr_clears (x, y, (mpfr_ptr) 0); + } + mpfr_clear (w); + } +} + int main (void) { @@ -339,6 +384,8 @@ main (void) tcmp2 (x, y, -1); } + test_equal (); + tests_end_mpfr (); return 0; diff --git a/tests/tcmpabs.c b/tests/tcmpabs.c index b35cccd36..61cbe1fc1 100644 --- a/tests/tcmpabs.c +++ b/tests/tcmpabs.c @@ -22,7 +22,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., #include "mpfr-test.h" -#define ERROR(s) do { printf(s); exit(1); } while (0) +#define PRINT_ERROR(s) do { printf ("%s", s); exit (1); } while (0) int main (void) @@ -39,67 +39,67 @@ main (void) MPFR_SET_NAN (xx); MPFR_SET_NAN (yy); if (mpfr_cmpabs (xx, yy) != 0) - ERROR ("mpfr_cmpabs (NAN,NAN) returns non-zero\n"); + PRINT_ERROR ("mpfr_cmpabs (NAN,NAN) returns non-zero\n"); if (!mpfr_erangeflag_p ()) - ERROR ("mpfr_cmpabs (NAN,NAN) doesn't set erange flag\n"); + PRINT_ERROR ("mpfr_cmpabs (NAN,NAN) doesn't set erange flag\n"); mpfr_set_str_binary (xx, "0.10E0"); mpfr_set_str_binary (yy, "-0.10E0"); if (mpfr_cmpabs (xx, yy) != 0) - ERROR ("mpfr_cmpabs (xx, yy) returns non-zero for prec=2\n"); + PRINT_ERROR ("mpfr_cmpabs (xx, yy) returns non-zero for prec=2\n"); mpfr_set_prec (xx, 65); mpfr_set_prec (yy, 65); mpfr_set_str_binary (xx, "-0.10011010101000110101010000000011001001001110001011101011111011101E623"); mpfr_set_str_binary (yy, "0.10011010101000110101010000000011001001001110001011101011111011100E623"); if (mpfr_cmpabs (xx, yy) <= 0) - ERROR ("Error (1) in mpfr_cmpabs\n"); + PRINT_ERROR ("Error (1) in mpfr_cmpabs\n"); mpfr_set_str_binary (xx, "-0.10100010001110110111000010001000010011111101000100011101000011100"); mpfr_set_str_binary (yy, "-0.10100010001110110111000010001000010011111101000100011101000011011"); if (mpfr_cmpabs (xx, yy) <= 0) - ERROR ("Error (2) in mpfr_cmpabs\n"); + PRINT_ERROR ("Error (2) in mpfr_cmpabs\n"); mpfr_set_prec (xx, 160); mpfr_set_prec (yy, 160); mpfr_set_str_binary (xx, "0.1E1"); mpfr_set_str_binary (yy, "-0.1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000110001110100"); if (mpfr_cmpabs (xx, yy) <= 0) - ERROR ("Error (3) in mpfr_cmpabs\n"); + PRINT_ERROR ("Error (3) in mpfr_cmpabs\n"); mpfr_set_prec(xx, 53); mpfr_set_prec(yy, 200); mpfr_set_ui (xx, 1, (mpfr_rnd_t) 0); mpfr_set_ui (yy, 1, (mpfr_rnd_t) 0); if (mpfr_cmpabs(xx, yy) != 0) - ERROR ("Error in mpfr_cmpabs: 1.0 != 1.0\n"); + PRINT_ERROR ("Error in mpfr_cmpabs: 1.0 != 1.0\n"); mpfr_set_prec (yy, 31); mpfr_set_str (xx, "-1.0000000002", 10, (mpfr_rnd_t) 0); mpfr_set_ui (yy, 1, (mpfr_rnd_t) 0); if (!(mpfr_cmpabs(xx,yy)>0)) - ERROR ("Error in mpfr_cmpabs: not 1.0000000002 > 1.0\n"); + PRINT_ERROR ("Error in mpfr_cmpabs: not 1.0000000002 > 1.0\n"); mpfr_set_prec(yy, 53); mpfr_set_ui(xx, 0, MPFR_RNDN); mpfr_set_str (yy, "-0.1", 10, MPFR_RNDN); if (mpfr_cmpabs(xx, yy) >= 0) - ERROR ("Error in mpfr_cmpabs(0.0, 0.1)\n"); + PRINT_ERROR ("Error in mpfr_cmpabs(0.0, 0.1)\n"); mpfr_set_inf (xx, -1); mpfr_set_str (yy, "23489745.0329", 10, MPFR_RNDN); if (mpfr_cmpabs(xx, yy) <= 0) - ERROR ("Error in mpfr_cmp(-Inf, 23489745.0329)\n"); + PRINT_ERROR ("Error in mpfr_cmp(-Inf, 23489745.0329)\n"); mpfr_set_inf (xx, 1); mpfr_set_inf (yy, -1); if (mpfr_cmpabs(xx, yy) != 0) - ERROR ("Error in mpfr_cmpabs(Inf, -Inf)\n"); + PRINT_ERROR ("Error in mpfr_cmpabs(Inf, -Inf)\n"); mpfr_set_inf (yy, -1); mpfr_set_str (xx, "2346.09234", 10, MPFR_RNDN); if (mpfr_cmpabs (xx, yy) >= 0) - ERROR ("Error in mpfr_cmpabs(-Inf, 2346.09234)\n"); + PRINT_ERROR ("Error in mpfr_cmpabs(-Inf, 2346.09234)\n"); mpfr_set_prec (xx, 2); mpfr_set_prec (yy, 128); @@ -108,10 +108,10 @@ main (void) "0.100000000000000000000000000000000000000000000000" "00000000000000000000000000000000000000000000001E10"); if (mpfr_cmpabs (xx, yy) >= 0) - ERROR ("Error in mpfr_cmpabs(10.235, 2346.09234)\n"); + PRINT_ERROR ("Error in mpfr_cmpabs(10.235, 2346.09234)\n"); mpfr_swap (xx, yy); if (mpfr_cmpabs(xx, yy) <= 0) - ERROR ("Error in mpfr_cmpabs(2346.09234, 10.235)\n"); + PRINT_ERROR ("Error in mpfr_cmpabs(2346.09234, 10.235)\n"); mpfr_swap (xx, yy); /* Check for NAN */ diff --git a/tests/terf.c b/tests/terf.c index d1ecd7f78..f3fda2e49 100644 --- a/tests/terf.c +++ b/tests/terf.c @@ -621,7 +621,7 @@ reduced_expo_range (void) mpfr_set_str (ex_y, "1.fffffffffffffffffffffe607440", 16, MPFR_RNDN); ex_inex = -1; ex_flags = MPFR_FLAGS_INEXACT; - if (SIGN (inex) != ex_inex || flags != ex_flags || + if (VSIGN (inex) != ex_inex || flags != ex_flags || ! mpfr_equal_p (y, ex_y)) { printf ("Error in reduced_expo_range\non x = "); @@ -631,7 +631,7 @@ reduced_expo_range (void) printf ("\n inex = %d, flags = %u\n", ex_inex, ex_flags); printf ("Got y = "); mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN); - printf ("\n inex = %d, flags = %u\n", SIGN (inex), flags); + printf ("\n inex = %d, flags = %u\n", VSIGN (inex), flags); exit (1); } mpfr_clears (x, y, ex_y, (mpfr_ptr) 0); diff --git a/tests/tests.c b/tests/tests.c index b64922072..ebcb81eb0 100644 --- a/tests/tests.c +++ b/tests/tests.c @@ -31,7 +31,10 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., #include <locale.h> #endif -#ifdef MPFR_TESTS_DIVBYZERO +#ifdef MPFR_TESTS_FPE_DIV +# ifdef MPFR_TESTS_FPE_TRAP +# define _GNU_SOURCE /* for feenableexcept */ +# endif # include <fenv.h> #endif @@ -235,6 +238,13 @@ test_version (void) exit (1); } +/* The inexact exception occurs very often, and is normal. + The underflow exception also might occur, for example in test_generic + for mpfr_xxx_d functions. Same for overflow. Thus we only check for + the division-by-zero and invalid exceptions, which should not occur + inside MPFR. */ +#define FPE_FLAGS (FE_DIVBYZERO | FE_INVALID) + void tests_start_mpfr (void) { @@ -254,9 +264,13 @@ tests_start_mpfr (void) set_fpu_prec (); #endif -#ifdef MPFR_TESTS_DIVBYZERO +#ifdef MPFR_TESTS_FPE_DIV /* Define to test the use of MPFR_ERRDIVZERO */ feclearexcept (FE_ALL_EXCEPT); +# ifdef MPFR_TESTS_FPE_TRAP + /* to trap the corresponding FP exceptions */ + feenableexcept (FPE_FLAGS); +# endif #endif if (!tests_memory_disabled) @@ -291,17 +305,20 @@ tests_end_mpfr (void) if (!tests_memory_disabled) tests_memory_end (); -#ifdef MPFR_TESTS_DIVBYZERO +#ifdef MPFR_TESTS_FPE_DIV /* Define to test the use of MPFR_ERRDIVZERO */ - if (fetestexcept (FE_DIVBYZERO|FE_INVALID)) + if (fetestexcept (FPE_FLAGS)) { - printf ("A floating-point division by 0 or an invalid operation" - " occurred!\n"); -#ifdef MPFR_ERRDIVZERO - /* This should never occur because the purpose of defining - MPFR_ERRDIVZERO is to avoid all the FP divisions by 0. */ + /* With MPFR_ERRDIVZERO, such exceptions should never occur + because the purpose of defining MPFR_ERRDIVZERO is to avoid + all the FP divisions by 0. */ + printf ("Some floating-point exception(s) occurred:"); + if (fetestexcept (FE_DIVBYZERO)) + printf (" DIVBYZERO"); /* e.g. from 1.0 / 0.0 to generate an inf */ + if (fetestexcept (FE_INVALID)) + printf (" INVALID"); /* e.g. from 0.0 / 0.0 to generate a NaN */ + printf ("\n"); err = 1; -#endif } #endif diff --git a/tests/texceptions.c b/tests/texceptions.c index 2f7178d0d..b0e7a39ae 100644 --- a/tests/texceptions.c +++ b/tests/texceptions.c @@ -22,7 +22,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., #include "mpfr-test.h" -#define ERROR(s) do { printf(s"\n"); exit(1); } while(0) +#define PRINT_ERROR(s) do { printf ("%s\n", s); exit (1); } while (0) /* Test powerof2 */ static void @@ -52,15 +52,15 @@ check_default_rnd (void) { printf ("%s %s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r), mpfr_print_rnd_mode (t)); - ERROR("ERROR in setting / getting default rounding mode (1)"); + PRINT_ERROR ("ERROR in setting / getting default rounding mode (1)"); } } mpfr_set_default_rounding_mode ((mpfr_rnd_t) MPFR_RND_MAX); if (mpfr_get_default_rounding_mode() != MPFR_RNDF) - ERROR("ERROR in setting / getting default rounding mode (2)"); + PRINT_ERROR ("ERROR in setting / getting default rounding mode (2)"); mpfr_set_default_rounding_mode((mpfr_rnd_t) -1); if (mpfr_get_default_rounding_mode() != MPFR_RNDF) - ERROR("ERROR in setting / getting default rounding mode (3)"); + PRINT_ERROR ("ERROR in setting / getting default rounding mode (3)"); } static void @@ -73,27 +73,27 @@ check_emin_emax (void) /* Check the functions not the macros ! */ if ((mpfr_set_emin)(MPFR_EMIN_MIN) != 0) - ERROR("set_emin failed!"); + PRINT_ERROR ("set_emin failed!"); if ((mpfr_get_emin)() != MPFR_EMIN_MIN) - ERROR("get_emin FAILED!"); + PRINT_ERROR ("get_emin FAILED!"); if ((mpfr_set_emin)(MPFR_EMIN_MIN-1) == 0) - ERROR("set_emin failed! (2)"); + PRINT_ERROR ("set_emin failed! (2)"); if ((mpfr_set_emax)(MPFR_EMAX_MAX) != 0) - ERROR("set_emax failed!"); + PRINT_ERROR ("set_emax failed!"); if ((mpfr_get_emax)() != MPFR_EMAX_MAX) - ERROR("get_emax FAILED!"); + PRINT_ERROR ("get_emax FAILED!"); if ((mpfr_set_emax)(MPFR_EMAX_MAX+1) == 0) - ERROR("set_emax failed! (2)"); + PRINT_ERROR ("set_emax failed! (2)"); if ((mpfr_get_emin_min) () != MPFR_EMIN_MIN) - ERROR ("get_emin_min"); + PRINT_ERROR ("get_emin_min"); if ((mpfr_get_emin_max) () != MPFR_EMIN_MAX) - ERROR ("get_emin_max"); + PRINT_ERROR ("get_emin_max"); if ((mpfr_get_emax_min) () != MPFR_EMAX_MIN) - ERROR ("get_emax_min"); + PRINT_ERROR ("get_emax_min"); if ((mpfr_get_emax_max) () != MPFR_EMAX_MAX) - ERROR ("get_emax_max"); + PRINT_ERROR ("get_emax_max"); set_emin (old_emin); set_emax (old_emax); @@ -106,7 +106,7 @@ check_set_get_prec (void) mpfr_init2 (x, 17); if (mpfr_get_prec (x) != 17 || (mpfr_get_prec)(x) != 17) - ERROR ("mpfr_get_prec"); + PRINT_ERROR ("mpfr_get_prec"); mpfr_clear (x); } @@ -115,10 +115,10 @@ mpfr_set_double_range (void) { mpfr_set_default_prec (54); if (mpfr_get_default_prec () != 54) - ERROR ("get_default_prec failed (1)"); + PRINT_ERROR ("get_default_prec failed (1)"); mpfr_set_default_prec (53); if ((mpfr_get_default_prec) () != 53) - ERROR ("get_default_prec failed (2)"); + PRINT_ERROR ("get_default_prec failed (2)"); /* in double precision format, the unbiased exponent is between 0 and 2047, where 0 is used for subnormal numbers, and 2047 for special @@ -154,32 +154,32 @@ check_flags (void) (mpfr_clear_overflow)(); mpfr_mul_2exp (x, x, 1024, MPFR_RNDN); if (!(mpfr_overflow_p)()) - ERROR("ERROR: No overflow detected!\n"); + PRINT_ERROR ("ERROR: No overflow detected!\n"); (mpfr_clear_underflow)(); mpfr_set_ui (x, 1, MPFR_RNDN); mpfr_div_2exp (x, x, 1025, MPFR_RNDN); if (!(mpfr_underflow_p)()) - ERROR("ERROR: No underflow detected!\n"); + PRINT_ERROR ("ERROR: No underflow detected!\n"); (mpfr_clear_nanflag)(); MPFR_SET_NAN(x); mpfr_add (x, x, x, MPFR_RNDN); if (!(mpfr_nanflag_p)()) - ERROR("ERROR: No NaN flag!\n"); + PRINT_ERROR ("ERROR: No NaN flag!\n"); (mpfr_clear_inexflag)(); mpfr_set_ui(x, 2, MPFR_RNDN); mpfr_cos(x, x, MPFR_RNDN); if (!(mpfr_inexflag_p)()) - ERROR("ERROR: No inexact flag!\n"); + PRINT_ERROR ("ERROR: No inexact flag!\n"); (mpfr_clear_erangeflag) (); mpfr_set_ui (x, 1, MPFR_RNDN); mpfr_mul_2exp (x, x, 1024, MPFR_RNDN); mpfr_get_ui (x, MPFR_RNDN); if (!(mpfr_erangeflag_p)()) - ERROR ("ERROR: No erange flag!\n"); + PRINT_ERROR ("ERROR: No erange flag!\n"); mpfr_clear (x); set_emin (old_emin); diff --git a/tests/tfma.c b/tests/tfma.c index 6f3d3a3f2..68a4d718b 100644 --- a/tests/tfma.c +++ b/tests/tfma.c @@ -217,10 +217,10 @@ test_underflow1 (void) /* |z| = 1 or 2^emax - ulp */ mpfr_clear_flags (); inex = mpfr_fma (r, x, y, z, (mpfr_rnd_t) rnd); -#define ERRTU1 "Error in test_underflow1 (signy = %d, signz = %d, %s)\n " +#define STRTU1 "Error in test_underflow1 (signy = %d, signz = %d, %s)\n " if (mpfr_nanflag_p ()) { - printf (ERRTU1 "NaN flag is set\n", signy, signz, + printf (STRTU1 "NaN flag is set\n", signy, signz, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); err = 1; } @@ -230,19 +230,19 @@ test_underflow1 (void) mpfr_nextabove (z); if ((mpfr_overflow_p () != 0) ^ (mpfr_inf_p (z) != 0)) { - printf (ERRTU1 "wrong overflow flag\n", signy, signz, + printf (STRTU1 "wrong overflow flag\n", signy, signz, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); err = 1; } if (mpfr_underflow_p ()) { - printf (ERRTU1 "underflow flag is set\n", signy, signz, + printf (STRTU1 "underflow flag is set\n", signy, signz, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); err = 1; } if (! mpfr_equal_p (r, z)) { - printf (ERRTU1 "got ", signy, signz, + printf (STRTU1 "got ", signy, signz, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); mpfr_print_binary (r); printf (" instead of "); @@ -254,7 +254,7 @@ test_underflow1 (void) (rnd == MPFR_RNDZ && signz > 0) || (rnd == MPFR_RNDN && signy > 0))) { - printf (ERRTU1 "ternary value = %d instead of < 0\n", + printf (STRTU1 "ternary value = %d instead of < 0\n", signy, signz, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), inex); err = 1; @@ -263,7 +263,7 @@ test_underflow1 (void) (rnd == MPFR_RNDZ && signz < 0) || (rnd == MPFR_RNDN && signy < 0))) { - printf (ERRTU1 "ternary value = %d instead of > 0\n", + printf (STRTU1 "ternary value = %d instead of > 0\n", signy, signz, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), inex); err = 1; @@ -300,10 +300,10 @@ test_underflow2 (void) */ mpfr_clear_flags (); inex = mpfr_fma (r, x, y, z, MPFR_RNDN); -#define ERRTU2 "Error in test_underflow2 (b = %d, i = %d)\n " +#define STRTU2 "Error in test_underflow2 (b = %d, i = %d)\n " if (__gmpfr_flags != MPFR_FLAGS_INEXACT) { - printf (ERRTU2 "flags = %u instead of %u\n", b, i, + printf (STRTU2 "flags = %u instead of %u\n", b, i, (unsigned int) __gmpfr_flags, (unsigned int) MPFR_FLAGS_INEXACT); err = 1; @@ -311,7 +311,7 @@ test_underflow2 (void) same = i == 15 || (i == 16 && b == 0); if (same ? (inex >= 0) : (inex <= 0)) { - printf (ERRTU2 "incorrect ternary value (%d instead of %c 0)\n", + printf (STRTU2 "incorrect ternary value (%d instead of %c 0)\n", b, i, inex, same ? '<' : '>'); err = 1; } @@ -320,7 +320,7 @@ test_underflow2 (void) mpfr_nextabove (y); if (! mpfr_equal_p (r, y)) { - printf (ERRTU2 "expected ", b, i); + printf (STRTU2 "expected ", b, i); mpfr_dump (y); printf (" got "); mpfr_dump (r); diff --git a/tests/tfms.c b/tests/tfms.c index be08fc5c6..66a8554b3 100644 --- a/tests/tfms.c +++ b/tests/tfms.c @@ -219,10 +219,10 @@ test_underflow1 (void) /* |z| = 1 or 2^emax - ulp */ mpfr_clear_flags (); inex = mpfr_fms (r, x, y, z, (mpfr_rnd_t) rnd); -#define ERRTU1 "Error in test_underflow1 (signy = %d, signz = %d, %s)\n " +#define STRTU1 "Error in test_underflow1 (signy = %d, signz = %d, %s)\n " if (mpfr_nanflag_p ()) { - printf (ERRTU1 "NaN flag is set\n", signy, signz, + printf (STRTU1 "NaN flag is set\n", signy, signz, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); err = 1; } @@ -233,19 +233,19 @@ test_underflow1 (void) mpfr_nextabove (z); if ((mpfr_overflow_p () != 0) ^ (mpfr_inf_p (z) != 0)) { - printf (ERRTU1 "wrong overflow flag\n", signy, signz, + printf (STRTU1 "wrong overflow flag\n", signy, signz, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); err = 1; } if (mpfr_underflow_p ()) { - printf (ERRTU1 "underflow flag is set\n", signy, signz, + printf (STRTU1 "underflow flag is set\n", signy, signz, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); err = 1; } if (! mpfr_equal_p (r, z)) { - printf (ERRTU1 "got ", signy, signz, + printf (STRTU1 "got ", signy, signz, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); mpfr_print_binary (r); printf (" instead of "); @@ -257,7 +257,7 @@ test_underflow1 (void) (rnd == MPFR_RNDZ && signz < 0) || (rnd == MPFR_RNDN && signy > 0))) { - printf (ERRTU1 "ternary value = %d instead of < 0\n", + printf (STRTU1 "ternary value = %d instead of < 0\n", signy, signz, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), inex); err = 1; @@ -266,7 +266,7 @@ test_underflow1 (void) (rnd == MPFR_RNDZ && signz > 0) || (rnd == MPFR_RNDN && signy < 0))) { - printf (ERRTU1 "ternary value = %d instead of > 0\n", + printf (STRTU1 "ternary value = %d instead of > 0\n", signy, signz, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), inex); err = 1; @@ -303,10 +303,10 @@ test_underflow2 (void) */ mpfr_clear_flags (); inex = mpfr_fms (r, x, y, z, MPFR_RNDN); -#define ERRTU2 "Error in test_underflow2 (b = %d, i = %d)\n " +#define STRTU2 "Error in test_underflow2 (b = %d, i = %d)\n " if (__gmpfr_flags != MPFR_FLAGS_INEXACT) { - printf (ERRTU2 "flags = %u instead of %u\n", b, i, + printf (STRTU2 "flags = %u instead of %u\n", b, i, (unsigned int) __gmpfr_flags, (unsigned int) MPFR_FLAGS_INEXACT); err = 1; @@ -314,7 +314,7 @@ test_underflow2 (void) same = i == 15 || (i == 16 && b == 0); if (same ? (inex >= 0) : (inex <= 0)) { - printf (ERRTU2 "incorrect ternary value (%d instead of %c 0)\n", + printf (STRTU2 "incorrect ternary value (%d instead of %c 0)\n", b, i, inex, same ? '<' : '>'); err = 1; } @@ -323,7 +323,7 @@ test_underflow2 (void) mpfr_nextabove (y); if (! mpfr_equal_p (r, y)) { - printf (ERRTU2 "expected ", b, i); + printf (STRTU2 "expected ", b, i); mpfr_dump (y); printf (" got "); mpfr_dump (r); diff --git a/tests/tgamma.c b/tests/tgamma.c index 11f126339..8a9e61dcd 100644 --- a/tests/tgamma.c +++ b/tests/tgamma.c @@ -586,9 +586,9 @@ exprange (void) printf ("Error in exprange (test1)\n"); printf ("x = "); mpfr_dump (x); - printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1); + printf ("Expected inex1 = %d, flags1 = %u, ", VSIGN (inex1), flags1); mpfr_dump (y); - printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2); + printf ("Got inex2 = %d, flags2 = %u, ", VSIGN (inex2), flags2); mpfr_dump (z); exit (1); } @@ -609,9 +609,9 @@ exprange (void) printf ("Error in exprange (test2)\n"); printf ("x = "); mpfr_dump (x); - printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1); + printf ("Expected inex1 = %d, flags1 = %u, ", VSIGN (inex1), flags1); mpfr_dump (y); - printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2); + printf ("Got inex2 = %d, flags2 = %u, ", VSIGN (inex2), flags2); mpfr_dump (z); exit (1); } @@ -631,9 +631,9 @@ exprange (void) printf ("Error in exprange (test3)\n"); printf ("x = "); mpfr_dump (x); - printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1); + printf ("Expected inex1 = %d, flags1 = %u, ", VSIGN (inex1), flags1); mpfr_dump (y); - printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2); + printf ("Got inex2 = %d, flags2 = %u, ", VSIGN (inex2), flags2); mpfr_dump (z); exit (1); } @@ -654,9 +654,9 @@ exprange (void) printf ("Error in exprange (test4)\n"); printf ("x = "); mpfr_dump (x); - printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1); + printf ("Expected inex1 = %d, flags1 = %u, ", VSIGN (inex1), flags1); mpfr_dump (y); - printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2); + printf ("Got inex2 = %d, flags2 = %u, ", VSIGN (inex2), flags2); mpfr_dump (z); exit (1); } @@ -679,9 +679,9 @@ exprange (void) printf ("Error in exprange (test5)\n"); printf ("x = "); mpfr_dump (x); - printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1); + printf ("Expected inex1 = %d, flags1 = %u, ", VSIGN (inex1), flags1); mpfr_dump (y); - printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2); + printf ("Got inex2 = %d, flags2 = %u, ", VSIGN (inex2), flags2); mpfr_dump (z); exit (1); } @@ -695,9 +695,9 @@ exprange (void) printf ("Error in exprange (test6)\n"); printf ("x = "); mpfr_dump (x); - printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1); + printf ("Expected inex1 = %d, flags1 = %u, ", VSIGN (inex1), flags1); mpfr_dump (y); - printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2); + printf ("Got inex2 = %d, flags2 = %u, ", VSIGN (inex2), flags2); mpfr_dump (z); exit (1); } @@ -713,9 +713,9 @@ exprange (void) printf ("Error in exprange (test7)\n"); printf ("x = "); mpfr_dump (x); - printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1); + printf ("Expected inex1 = %d, flags1 = %u, ", VSIGN (inex1), flags1); mpfr_dump (y); - printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2); + printf ("Got inex2 = %d, flags2 = %u, ", VSIGN (inex2), flags2); mpfr_dump (z); exit (1); } @@ -733,9 +733,9 @@ exprange (void) printf ("Error in exprange (test8)\n"); printf ("x = "); mpfr_dump (x); - printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1); + printf ("Expected inex1 = %d, flags1 = %u, ", VSIGN (inex1), flags1); mpfr_dump (y); - printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2); + printf ("Got inex2 = %d, flags2 = %u, ", VSIGN (inex2), flags2); mpfr_dump (z); exit (1); } @@ -749,9 +749,9 @@ exprange (void) printf ("Error in exprange (test9)\n"); printf ("x = "); mpfr_dump (x); - printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1); + printf ("Expected inex1 = %d, flags1 = %u, ", VSIGN (inex1), flags1); mpfr_dump (y); - printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2); + printf ("Got inex2 = %d, flags2 = %u, ", VSIGN (inex2), flags2); mpfr_dump (z); exit (1); } @@ -768,9 +768,9 @@ exprange (void) printf ("Error in exprange (test10)\n"); printf ("x = "); mpfr_dump (x); - printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1); + printf ("Expected inex1 = %d, flags1 = %u, ", VSIGN (inex1), flags1); mpfr_dump (y); - printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2); + printf ("Got inex2 = %d, flags2 = %u, ", VSIGN (inex2), flags2); mpfr_dump (z); exit (1); } @@ -841,7 +841,7 @@ tiny_aux (int stop, mpfr_exp_t e) mpfr_dump (x); printf (" expected inex = %2d, ", expected_inex); mpfr_dump (z); - printf (" got inex = %2d, ", SIGN (inex)); + printf (" got inex = %2d, ", VSIGN (inex)); mpfr_dump (y); printf (" expected flags = %u, got %u\n", expected_flags, flags); diff --git a/tests/tget_f.c b/tests/tget_f.c index 3e2bfd2e3..41e80bf3c 100644 --- a/tests/tget_f.c +++ b/tests/tget_f.c @@ -20,6 +20,7 @@ along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ +#define MPFR_NEED_MPF_INTERNALS #include "mpfr-test.h" #ifndef MPFR_USE_MINI_GMP diff --git a/tests/tget_set_d64.c b/tests/tget_set_d64.c index 883b64c45..6f1203dc8 100644 --- a/tests/tget_set_d64.c +++ b/tests/tget_set_d64.c @@ -67,10 +67,10 @@ print_decimal64 (_Decimal64 d) } #endif /* _MPFR_IEEE_FLOATS */ -#define ERR_MISC(V) \ +#define PRINT_ERR_MISC(V) \ do \ { \ - printf ("Error in check_misc for " V ".\n"); \ + printf ("Error in check_misc for %s.\n", V); \ printf (" mpfr_get_decimal64() returned: "); \ print_decimal64 (d); \ printf (" mpfr_set_decimal64() set x to: "); \ @@ -91,6 +91,7 @@ check_misc (void) mpfr_init2 (x, 123); mpfr_init2 (y, 123); +#if !defined(MPFR_ERRDIVZERO) mpfr_set_nan (x); d = mpfr_get_decimal64 (x, MPFR_RNDZ); mpfr_set_ui (x, 1, MPFR_RNDZ); @@ -102,21 +103,22 @@ check_misc (void) mpfr_set_ui (x, 1, MPFR_RNDZ); mpfr_set_decimal64 (x, d, MPFR_RNDZ); if (! mpfr_inf_p (x) || MPFR_IS_NEG (x)) - ERR_MISC ("+Inf"); + PRINT_ERR_MISC ("+Inf"); mpfr_set_inf (x, -1); d = mpfr_get_decimal64 (x, MPFR_RNDZ); mpfr_set_ui (x, 1, MPFR_RNDZ); mpfr_set_decimal64 (x, d, MPFR_RNDZ); if (! mpfr_inf_p (x) || MPFR_IS_POS (x)) - ERR_MISC ("-Inf"); + PRINT_ERR_MISC ("-Inf"); +#endif mpfr_set_ui (x, 0, MPFR_RNDZ); d = mpfr_get_decimal64 (x, MPFR_RNDZ); mpfr_set_ui (x, 1, MPFR_RNDZ); mpfr_set_decimal64 (x, d, MPFR_RNDZ); if (MPFR_NOTZERO (x) || MPFR_IS_NEG (x)) - ERR_MISC ("+0"); + PRINT_ERR_MISC ("+0"); mpfr_set_ui (x, 0, MPFR_RNDZ); mpfr_neg (x, x, MPFR_RNDZ); @@ -124,35 +126,35 @@ check_misc (void) mpfr_set_ui (x, 1, MPFR_RNDZ); mpfr_set_decimal64 (x, d, MPFR_RNDZ); if (MPFR_NOTZERO (x) || MPFR_IS_POS (x)) - ERR_MISC ("-0"); + PRINT_ERR_MISC ("-0"); mpfr_set_ui (x, 1, MPFR_RNDZ); d = mpfr_get_decimal64 (x, MPFR_RNDZ); mpfr_set_ui (x, 0, MPFR_RNDZ); mpfr_set_decimal64 (x, d, MPFR_RNDZ); if (mpfr_cmp_ui (x, 1) != 0) - ERR_MISC ("+1"); + PRINT_ERR_MISC ("+1"); mpfr_set_si (x, -1, MPFR_RNDZ); d = mpfr_get_decimal64 (x, MPFR_RNDZ); mpfr_set_ui (x, 0, MPFR_RNDZ); mpfr_set_decimal64 (x, d, MPFR_RNDZ); if (mpfr_cmp_si (x, -1) != 0) - ERR_MISC ("-1"); + PRINT_ERR_MISC ("-1"); mpfr_set_ui (x, 2, MPFR_RNDZ); d = mpfr_get_decimal64 (x, MPFR_RNDZ); mpfr_set_ui (x, 0, MPFR_RNDZ); mpfr_set_decimal64 (x, d, MPFR_RNDZ); if (mpfr_cmp_ui (x, 2) != 0) - ERR_MISC ("2"); + PRINT_ERR_MISC ("2"); mpfr_set_ui (x, 99, MPFR_RNDZ); d = mpfr_get_decimal64 (x, MPFR_RNDZ); mpfr_set_ui (x, 0, MPFR_RNDZ); mpfr_set_decimal64 (x, d, MPFR_RNDZ); if (mpfr_cmp_ui (x, 99) != 0) - ERR_MISC ("99"); + PRINT_ERR_MISC ("99"); mpfr_set_str (x, "9999999999999999", 10, MPFR_RNDZ); mpfr_set (y, x, MPFR_RNDZ); @@ -160,7 +162,7 @@ check_misc (void) mpfr_set_ui (x, 0, MPFR_RNDZ); mpfr_set_decimal64 (x, d, MPFR_RNDZ); if (! mpfr_equal_p (x, y)) - ERR_MISC ("9999999999999999"); + PRINT_ERR_MISC ("9999999999999999"); /* smallest normal number */ mpfr_set_str (x, "1E-383", 10, MPFR_RNDU); @@ -169,7 +171,7 @@ check_misc (void) mpfr_set_ui (x, 0, MPFR_RNDZ); mpfr_set_decimal64 (x, d, MPFR_RNDU); if (! mpfr_equal_p (x, y)) - ERR_MISC ("1E-383"); + PRINT_ERR_MISC ("1E-383"); /* smallest subnormal number */ mpfr_set_str (x, "1E-398", 10, MPFR_RNDU); @@ -178,7 +180,7 @@ check_misc (void) mpfr_set_ui (x, 0, MPFR_RNDZ); mpfr_set_decimal64 (x, d, MPFR_RNDU); if (! mpfr_equal_p (x, y)) - ERR_MISC ("1E-398"); + PRINT_ERR_MISC ("1E-398"); /* subnormal number with exponent change when we round back from 16 digits to 1 digit */ @@ -188,7 +190,7 @@ check_misc (void) mpfr_set_decimal64 (x, d, MPFR_RNDD); mpfr_set_str (y, "1E-397", 10, MPFR_RNDN); if (! mpfr_equal_p (x, y)) - ERR_MISC ("9.9E-398"); + PRINT_ERR_MISC ("9.9E-398"); /* largest number */ mpfr_set_str (x, "9.999999999999999E384", 10, MPFR_RNDZ); @@ -199,7 +201,7 @@ check_misc (void) mpfr_set_ui (x, 0, MPFR_RNDZ); mpfr_set_decimal64 (x, d, MPFR_RNDZ); if (! mpfr_equal_p (x, y)) - ERR_MISC ("DEC64_MAX"); + PRINT_ERR_MISC ("DEC64_MAX"); } else { @@ -217,7 +219,7 @@ check_misc (void) mpfr_set_ui (x, 0, MPFR_RNDZ); mpfr_set_decimal64 (x, d, MPFR_RNDZ); if (! mpfr_equal_p (x, y)) - ERR_MISC ("-DEC64_MAX"); + PRINT_ERR_MISC ("-DEC64_MAX"); } else { @@ -235,7 +237,7 @@ check_misc (void) d = mpfr_get_decimal64 (x, MPFR_RNDZ); mpfr_set_decimal64 (y, d, MPFR_RNDU); if (! mpfr_equal_p (x, y)) - ERR_MISC ("DEC64_MAX (2)"); + PRINT_ERR_MISC ("DEC64_MAX (2)"); mpfr_clear (x); mpfr_clear (y); @@ -397,7 +399,9 @@ main (void) check_misc (); check_random (); check_native (); +#if !defined(MPFR_ERRDIVZERO) check_overflow (); +#endif check_tiny (); tests_end_mpfr (); diff --git a/tests/tl2b.c b/tests/tl2b.c index 3af7a51c1..5a1eb05e0 100644 --- a/tests/tl2b.c +++ b/tests/tl2b.c @@ -96,7 +96,7 @@ compute_l2b (int output) mpfr_srcptr t; int beta, i; int error = 0; - char buffer[30]; + char buffer[256]; /* larger than needed, for maintainability */ if (output) printf ("#ifndef UINT64_C\n# define UINT64_C(c) c\n#endif\n\n"); diff --git a/tests/tmul_2exp.c b/tests/tmul_2exp.c index 65b53dcc5..c90e482fb 100644 --- a/tests/tmul_2exp.c +++ b/tests/tmul_2exp.c @@ -112,11 +112,11 @@ underflow (mpfr_exp_t e) printf ("Expected "); mpfr_out_str (stdout, 16, 0, z1, MPFR_RNDN); printf (", inex = %d, flags = %u\n", - SIGN (inex1), flags1); + VSIGN (inex1), flags1); printf ("Got "); mpfr_out_str (stdout, 16, 0, z2, MPFR_RNDN); printf (", inex = %d, flags = %u\n", - SIGN (inex2), flags2); + VSIGN (inex2), flags2); exit (1); } /* div */ } /* k */ diff --git a/tests/tpow_all.c b/tests/tpow_all.c index 5a7e9339e..f8ca5e653 100644 --- a/tests/tpow_all.c +++ b/tests/tpow_all.c @@ -113,12 +113,12 @@ cmpres (int spx, const void *px, const char *sy, mpfr_rnd_t rnd, else { mpfr_out_str (stdout, 16, 0, z1, MPFR_RNDN); - printf (", inex = %d,\n flags =", SIGN (inex1)); + printf (", inex = %d,\n flags =", VSIGN (inex1)); flags_out (flags1); } printf ("Got "); mpfr_out_str (stdout, 16, 0, z2, MPFR_RNDN); - printf (", inex = %d,\n flags =", SIGN (inex2)); + printf (", inex = %d,\n flags =", VSIGN (inex2)); flags_out (flags2); if (all_cmpres_errors != 0) all_cmpres_errors = -1; @@ -494,7 +494,7 @@ underflow_up1 (void) for (i = 0; i <= 12; i++) { unsigned int flags = 0; - char sy[16]; + char sy[256]; /* larger than needed, for maintainability */ /* Test 2^(emin - i/4). * --> Underflow iff i > 4. diff --git a/tests/tpow_z.c b/tests/tpow_z.c index 36af69d1e..0bfaae2f8 100644 --- a/tests/tpow_z.c +++ b/tests/tpow_z.c @@ -25,7 +25,8 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., #include "mpfr-test.h" -#define ERROR(str) do { printf ("Error for " str "\n"); exit (1); } while (0) +#define PRINT_ERROR(str) \ + do { printf ("Error for %s\n", str); exit (1); } while (0) static void check_special (void) @@ -43,93 +44,93 @@ check_special (void) mpz_set_ui (z, 0); res = mpfr_pow_z (y, x, z, MPFR_RNDN); if (res != 0 || mpfr_cmp_ui (y, 1) != 0) - ERROR ("23^0"); + PRINT_ERROR ("23^0"); mpfr_set_nan (x); res = mpfr_pow_z (y, x, z, MPFR_RNDN); if (res != 0 || mpfr_nan_p (y) || mpfr_cmp_si (y, 1) != 0) - ERROR ("NAN^0"); + PRINT_ERROR ("NAN^0"); mpfr_set_inf (x, 1); res = mpfr_pow_z (y, x, z, MPFR_RNDN); if (res != 0 || mpfr_cmp_ui (y, 1) != 0) - ERROR ("INF^0"); + PRINT_ERROR ("INF^0"); /* sINF^N = INF if s==1 or n even if N > 0*/ mpz_set_ui (z, 42); mpfr_set_inf (x, 1); res = mpfr_pow_z (y, x, z, MPFR_RNDN); if (res != 0 || mpfr_inf_p (y) == 0 || mpfr_sgn (y) <= 0) - ERROR ("INF^42"); + PRINT_ERROR ("INF^42"); mpfr_set_inf (x, -1); res = mpfr_pow_z (y, x, z, MPFR_RNDN); if (res != 0 || mpfr_inf_p (y) == 0 || mpfr_sgn (y) <= 0) - ERROR ("-INF^42"); + PRINT_ERROR ("-INF^42"); mpz_set_ui (z, 17); mpfr_set_inf (x, 1); res = mpfr_pow_z (y, x, z, MPFR_RNDN); if (res != 0 || mpfr_inf_p (y) == 0 || mpfr_sgn (y) <= 0) - ERROR ("INF^17"); + PRINT_ERROR ("INF^17"); mpfr_set_inf (x, -1); res = mpfr_pow_z (y, x, z, MPFR_RNDN); if (res != 0 || mpfr_inf_p (y) == 0 || mpfr_sgn (y) >= 0) - ERROR ("-INF^17"); + PRINT_ERROR ("-INF^17"); mpz_set_si (z, -42); mpfr_set_inf (x, 1); res = mpfr_pow_z (y, x, z, MPFR_RNDN); if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_IS_NEG (y)) - ERROR ("INF^-42"); + PRINT_ERROR ("INF^-42"); mpfr_set_inf (x, -1); res = mpfr_pow_z (y, x, z, MPFR_RNDN); if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_IS_NEG (y)) - ERROR ("-INF^-42"); + PRINT_ERROR ("-INF^-42"); mpz_set_si (z, -17); mpfr_set_inf (x, 1); res = mpfr_pow_z (y, x, z, MPFR_RNDN); if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_IS_NEG (y)) - ERROR ("INF^-17"); + PRINT_ERROR ("INF^-17"); mpfr_set_inf (x, -1); res = mpfr_pow_z (y, x, z, MPFR_RNDN); if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_IS_POS (y)) - ERROR ("-INF^-17"); + PRINT_ERROR ("-INF^-17"); /* s0^N = +0 if s==+ or n even if N > 0*/ mpz_set_ui (z, 42); MPFR_SET_ZERO (x); MPFR_SET_POS (x); res = mpfr_pow_z (y, x, z, MPFR_RNDN); if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_IS_NEG (y)) - ERROR ("+0^42"); + PRINT_ERROR ("+0^42"); MPFR_SET_NEG (x); res = mpfr_pow_z (y, x, z, MPFR_RNDN); if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_IS_NEG (y)) - ERROR ("-0^42"); + PRINT_ERROR ("-0^42"); mpz_set_ui (z, 17); MPFR_SET_POS (x); res = mpfr_pow_z (y, x, z, MPFR_RNDN); if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_IS_NEG (y)) - ERROR ("+0^17"); + PRINT_ERROR ("+0^17"); MPFR_SET_NEG (x); res = mpfr_pow_z (y, x, z, MPFR_RNDN); if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_IS_POS (y)) - ERROR ("-0^17"); + PRINT_ERROR ("-0^17"); mpz_set_si (z, -42); MPFR_SET_ZERO (x); MPFR_SET_POS (x); res = mpfr_pow_z (y, x, z, MPFR_RNDN); if (res != 0 || mpfr_inf_p (y) == 0 || MPFR_IS_NEG (y)) - ERROR ("+0^-42"); + PRINT_ERROR ("+0^-42"); MPFR_SET_NEG (x); res = mpfr_pow_z (y, x, z, MPFR_RNDN); if (res != 0 || mpfr_inf_p (y) == 0 || MPFR_IS_NEG (y)) - ERROR ("-0^-42"); + PRINT_ERROR ("-0^-42"); mpz_set_si (z, -17); MPFR_SET_POS (x); res = mpfr_pow_z (y, x, z, MPFR_RNDN); if (res != 0 || mpfr_inf_p (y) == 0 || MPFR_IS_NEG (y)) - ERROR ("+0^-17"); + PRINT_ERROR ("+0^-17"); MPFR_SET_NEG (x); res = mpfr_pow_z (y, x, z, MPFR_RNDN); if (res != 0 || mpfr_inf_p (y) == 0 || MPFR_IS_POS (y)) - ERROR ("-0^-17"); + PRINT_ERROR ("-0^-17"); mpz_clear (z); mpfr_clear (y); diff --git a/tests/tprintf.c b/tests/tprintf.c index 7767a9052..20c7a658c 100644 --- a/tests/tprintf.c +++ b/tests/tprintf.c @@ -29,6 +29,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., #include <stdarg.h> #include <stddef.h> +#include <errno.h> #include "mpfr-intmax.h" #include "mpfr-test.h" @@ -91,22 +92,32 @@ check_vprintf (const char *fmt, ...) va_end (ap); } -static void +static unsigned int check_vprintf_failure (const char *fmt, ...) { va_list ap; + int r, e; va_start (ap, fmt); - if (mpfr_vprintf (fmt, ap) != -1) - { - putchar ('\n'); - fprintf (stderr, "Error 3 in mpfr_vprintf(\"%s\", ...)\n", fmt); + errno = 0; + r = mpfr_vprintf (fmt, ap); + e = errno; + va_end (ap); - va_end (ap); - exit (1); + if (r != -1 +#ifdef EOVERFLOW + || e != EOVERFLOW +#endif + ) + { + putchar ('\n'); + fprintf (stderr, "Error 3 in mpfr_vprintf(\"%s\", ...)\n" + "Got r = %d, errno = %d\n", fmt, r, e); + return 1; } + putchar ('\n'); - va_end (ap); + return 0; } /* The goal of this test is to check cases where more INT_MAX characters @@ -142,10 +153,10 @@ check_long_string (void) increase is necessary, but is not guaranteed to be sufficient in all cases (e.g. with logging activated). */ min_memory_limit = large_prec / MPFR_BYTES_PER_MP_LIMB; - if (min_memory_limit > (size_t) -1 / 12) + if (min_memory_limit > (size_t) -1 / 32) min_memory_limit = (size_t) -1; else - min_memory_limit *= 12; + min_memory_limit *= 32; if (tests_memory_limit > 0 && tests_memory_limit < min_memory_limit) tests_memory_limit = min_memory_limit; @@ -156,8 +167,44 @@ check_long_string (void) if (large_prec >= INT_MAX - 512) { - check_vprintf_failure ("%Rb %512d", x, 1); - check_vprintf_failure ("%RA %RA %Ra %Ra %512d", x, x, x, x, 1); + unsigned int err = 0; + +#define LS1 "%Rb %512d" +#define LS2 "%RA %RA %Ra %Ra %512d" + + err |= check_vprintf_failure (LS1, x, 1); + err |= check_vprintf_failure (LS2, x, x, x, x, 1); + + if (sizeof (long) * CHAR_BIT > 40) + { + long n1, n2; + + n1 = large_prec + 517; + n2 = -17; + err |= check_vprintf_failure (LS1 "%ln", x, 1, &n2); + if (n1 != n2) + { + fprintf (stderr, "Error in check_long_string(\"%s\", ...)\n" + "Expected n = %ld\n" + "Got n = %ld\n", + LS1 "%ln", n1, n2); + err = 1; + } + n1 = ((large_prec - 2) / 4) * 4 + 548; + n2 = -17; + err |= check_vprintf_failure (LS2 "%ln", x, x, x, x, 1, &n2); + if (n1 != n2) + { + fprintf (stderr, "Error in check_long_string(\"%s\", ...)\n" + "Expected n = %ld\n" + "Got n = %ld\n", + LS2 "%ln", n1, n2); + err = 1; + } + } + + if (err) + exit (1); } mpfr_clear (x); diff --git a/tests/tset_ld.c b/tests/tset_ld.c index b0e1d9e08..d8431e3ce 100644 --- a/tests/tset_ld.c +++ b/tests/tset_ld.c @@ -625,7 +625,9 @@ main (int argc, char *argv[]) test_small (); check_subnormal (); +#if !defined(MPFR_ERRDIVZERO) check_overflow (); +#endif test_20140212 (); bug_20160907 (); diff --git a/tests/tset_si.c b/tests/tset_si.c index f4694c828..7bd66a70e 100644 --- a/tests/tset_si.c +++ b/tests/tset_si.c @@ -22,7 +22,8 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., #include "mpfr-test.h" -#define ERROR(str) do { printf ("Error for " str "\n"); exit (1); } while (0) +#define PRINT_ERROR(str) \ + do { printf ("Error for %s\n", str); exit (1); } while (0) static void test_2exp (void) @@ -34,57 +35,57 @@ test_2exp (void) mpfr_set_ui_2exp (x, 1, 0, MPFR_RNDN); if (mpfr_cmp_ui (x, 1) != 0) - ERROR ("(1U,0)"); + PRINT_ERROR ("(1U,0)"); mpfr_set_ui_2exp (x, 1024, -10, MPFR_RNDN); if (mpfr_cmp_ui(x, 1) != 0) - ERROR ("(1024U,-10)"); + PRINT_ERROR ("(1024U,-10)"); mpfr_set_ui_2exp (x, 1024, 10, MPFR_RNDN); if (mpfr_cmp_ui (x, 1024 * 1024) != 0) - ERROR ("(1024U,+10)"); + PRINT_ERROR ("(1024U,+10)"); mpfr_set_si_2exp (x, -1024L * 1024L, -10, MPFR_RNDN); if (mpfr_cmp_si (x, -1024) != 0) - ERROR ("(1M,-10)"); + PRINT_ERROR ("(1M,-10)"); mpfr_set_ui_2exp (x, 0x92345678, 16, MPFR_RNDN); if (mpfr_cmp_str (x, "92345678@4", 16, MPFR_RNDN) != 0) - ERROR ("(x92345678U,+16)"); + PRINT_ERROR ("(x92345678U,+16)"); mpfr_set_si_2exp (x, -0x1ABCDEF0, -256, MPFR_RNDN); if (mpfr_cmp_str (x, "-1ABCDEF0@-64", 16, MPFR_RNDN) != 0) - ERROR ("(-x1ABCDEF0,-256)"); + PRINT_ERROR ("(-x1ABCDEF0,-256)"); mpfr_set_prec (x, 2); res = mpfr_set_si_2exp (x, 7, 10, MPFR_RNDU); if (mpfr_cmp_ui (x, 1<<13) != 0 || res <= 0) - ERROR ("Prec 2 + si_2exp"); + PRINT_ERROR ("Prec 2 + si_2exp"); res = mpfr_set_ui_2exp (x, 7, 10, MPFR_RNDU); if (mpfr_cmp_ui (x, 1<<13) != 0 || res <= 0) - ERROR ("Prec 2 + ui_2exp"); + PRINT_ERROR ("Prec 2 + ui_2exp"); mpfr_clear_flags (); mpfr_set_ui_2exp (x, 17, MPFR_EMAX_MAX, MPFR_RNDN); if (!mpfr_inf_p (x) || MPFR_IS_NEG (x)) - ERROR ("mpfr_set_ui_2exp and overflow (bad result)"); + PRINT_ERROR ("mpfr_set_ui_2exp and overflow (bad result)"); if (!mpfr_overflow_p ()) - ERROR ("mpfr_set_ui_2exp and overflow (overflow flag not set)"); + PRINT_ERROR ("mpfr_set_ui_2exp and overflow (overflow flag not set)"); mpfr_clear_flags (); mpfr_set_si_2exp (x, 17, MPFR_EMAX_MAX, MPFR_RNDN); if (!mpfr_inf_p (x) || MPFR_IS_NEG (x)) - ERROR ("mpfr_set_si_2exp (pos) and overflow (bad result)"); + PRINT_ERROR ("mpfr_set_si_2exp (pos) and overflow (bad result)"); if (!mpfr_overflow_p ()) - ERROR ("mpfr_set_si_2exp (pos) and overflow (overflow flag not set)"); + PRINT_ERROR ("mpfr_set_si_2exp (pos) and overflow (overflow flag not set)"); mpfr_clear_flags (); mpfr_set_si_2exp (x, -17, MPFR_EMAX_MAX, MPFR_RNDN); if (!mpfr_inf_p (x) || MPFR_IS_POS (x)) - ERROR ("mpfr_set_si_2exp (neg) and overflow (bad result)"); + PRINT_ERROR ("mpfr_set_si_2exp (neg) and overflow (bad result)"); if (!mpfr_overflow_p ()) - ERROR ("mpfr_set_si_2exp (neg) and overflow (overflow flag not set)"); + PRINT_ERROR ("mpfr_set_si_2exp (neg) and overflow (overflow flag not set)"); mpfr_clear (x); } diff --git a/tests/tset_sj.c b/tests/tset_sj.c index 4c8940c32..9435f0fca 100644 --- a/tests/tset_sj.c +++ b/tests/tset_sj.c @@ -39,7 +39,8 @@ main (void) #else -#define ERROR(str) do { printf ("Error for " str "\n"); exit (1); } while (0) +#define PRINT_ERROR(str) \ + do { printf ("Error for %s\n", str); exit (1); } while (0) static int inexact_sign (int x) @@ -88,14 +89,14 @@ check_set_uj (mpfr_prec_t pmin, mpfr_prec_t pmax, int N) mpfr_set_prec (x, sizeof(uintmax_t)*CHAR_BIT); inex1 = mpfr_set_uj (x, MPFR_UINTMAX_MAX, MPFR_RNDN); if (inex1 != 0 || mpfr_sgn(x) <= 0) - ERROR ("inexact / UINTMAX_MAX"); + PRINT_ERROR ("inexact / UINTMAX_MAX"); inex1 = mpfr_add_ui (x, x, 1, MPFR_RNDN); if (inex1 != 0 || !mpfr_powerof2_raw (x) || MPFR_EXP (x) != sizeof(uintmax_t) * CHAR_BIT + 1) - ERROR ("power of 2"); + PRINT_ERROR ("power of 2"); mpfr_set_uj (x, 0, MPFR_RNDN); if (!MPFR_IS_ZERO (x)) - ERROR ("Setting 0"); + PRINT_ERROR ("Setting 0"); mpfr_clears (x, y, (mpfr_ptr) 0); } @@ -110,30 +111,30 @@ check_set_uj_2exp (void) inex = mpfr_set_uj_2exp (x, 1, 0, MPFR_RNDN); if (inex || mpfr_cmp_ui(x, 1)) - ERROR ("(1U,0)"); + PRINT_ERROR ("(1U,0)"); inex = mpfr_set_uj_2exp (x, 1024, -10, MPFR_RNDN); if (inex || mpfr_cmp_ui(x, 1)) - ERROR ("(1024U,-10)"); + PRINT_ERROR ("(1024U,-10)"); inex = mpfr_set_uj_2exp (x, 1024, 10, MPFR_RNDN); if (inex || mpfr_cmp_ui(x, 1024L * 1024L)) - ERROR ("(1024U,+10)"); + PRINT_ERROR ("(1024U,+10)"); inex = mpfr_set_uj_2exp (x, MPFR_UINTMAX_MAX, 1000, MPFR_RNDN); inex |= mpfr_div_2ui (x, x, 1000, MPFR_RNDN); inex |= mpfr_add_ui (x, x, 1, MPFR_RNDN); if (inex || !mpfr_powerof2_raw (x) || MPFR_EXP (x) != sizeof(uintmax_t) * CHAR_BIT + 1) - ERROR ("(UINTMAX_MAX)"); + PRINT_ERROR ("(UINTMAX_MAX)"); inex = mpfr_set_uj_2exp (x, MPFR_UINTMAX_MAX, MPFR_EMAX_MAX-10, MPFR_RNDN); if (inex == 0 || !mpfr_inf_p (x)) - ERROR ("Overflow"); + PRINT_ERROR ("Overflow"); inex = mpfr_set_uj_2exp (x, MPFR_UINTMAX_MAX, MPFR_EMIN_MIN-1000, MPFR_RNDN); if (inex == 0 || !MPFR_IS_ZERO (x)) - ERROR ("Underflow"); + PRINT_ERROR ("Underflow"); mpfr_clear (x); } @@ -150,11 +151,11 @@ check_set_sj (void) inex |= mpfr_add_si (x, x, -1, MPFR_RNDN); if (inex || mpfr_sgn (x) >=0 || !mpfr_powerof2_raw (x) || MPFR_EXP (x) != sizeof(intmax_t) * CHAR_BIT) - ERROR ("set_sj (-INTMAX_MAX)"); + PRINT_ERROR ("set_sj (-INTMAX_MAX)"); inex = mpfr_set_sj (x, 1742, MPFR_RNDN); if (inex || mpfr_cmp_ui (x, 1742)) - ERROR ("set_sj (1742)"); + PRINT_ERROR ("set_sj (1742)"); mpfr_clear (x); } @@ -170,7 +171,7 @@ check_set_sj_2exp (void) inex = mpfr_set_sj_2exp (x, MPFR_INTMAX_MIN, 1000, MPFR_RNDN); if (inex || mpfr_sgn (x) >=0 || !mpfr_powerof2_raw (x) || MPFR_EXP (x) != sizeof(intmax_t) * CHAR_BIT + 1000) - ERROR ("set_sj_2exp (INTMAX_MIN)"); + PRINT_ERROR ("set_sj_2exp (INTMAX_MIN)"); mpfr_clear (x); } diff --git a/tests/tsi_op.c b/tests/tsi_op.c index 88f1432f0..824178d54 100644 --- a/tests/tsi_op.c +++ b/tests/tsi_op.c @@ -27,7 +27,7 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., tgeneric_ui.c should probably be replaced by tgeneric.c, with some changes, since tgeneric.c does more checks. */ -#define ERROR1(s,i,z,exp) \ +#define PRINT_ERROR1(s,i,z,exp) \ do \ { \ printf ("Error for " s " and i=%d\n", i); \ @@ -117,28 +117,28 @@ main (int argc, char *argv[]) y = tab[i].op2; mpfr_add_si (z, x, y, MPFR_RNDZ); if (mpfr_cmp_str (z, tab[i].res_add, 16, MPFR_RNDN)) - ERROR1("add_si", i, z, tab[i].res_add); + PRINT_ERROR1 ("add_si", i, z, tab[i].res_add); mpfr_sub_si (z, x, y, MPFR_RNDZ); if (mpfr_cmp_str (z, tab[i].res_sub, 16, MPFR_RNDN)) - ERROR1("sub_si", i, z, tab[i].res_sub); + PRINT_ERROR1 ("sub_si", i, z, tab[i].res_sub); mpfr_si_sub (z, y, x, MPFR_RNDZ); mpfr_neg (z, z, MPFR_RNDZ); if (mpfr_cmp_str (z, tab[i].res_sub, 16, MPFR_RNDN)) - ERROR1("si_sub", i, z, tab[i].res_sub); + PRINT_ERROR1 ("si_sub", i, z, tab[i].res_sub); mpfr_mul_si (z, x, y, MPFR_RNDZ); if (mpfr_cmp_str (z, tab[i].res_mul, 16, MPFR_RNDN)) - ERROR1("mul_si", i, z, tab[i].res_mul); + PRINT_ERROR1 ("mul_si", i, z, tab[i].res_mul); mpfr_div_si (z, x, y, MPFR_RNDZ); if (mpfr_cmp_str (z, tab[i].res_div, 16, MPFR_RNDN)) - ERROR1("div_si", i, z, tab[i].res_div); + PRINT_ERROR1 ("div_si", i, z, tab[i].res_div); } mpfr_set_str1 (x, "1"); mpfr_si_div (z, 1024, x, MPFR_RNDN); if (mpfr_cmp_str1 (z, "1024")) - ERROR1("si_div", i, z, "1024"); + PRINT_ERROR1 ("si_div", i, z, "1024"); mpfr_si_div (z, -1024, x, MPFR_RNDN); if (mpfr_cmp_str1 (z, "-1024")) - ERROR1("si_div", i, z, "-1024"); + PRINT_ERROR1 ("si_div", i, z, "-1024"); mpfr_clears (x, z, (mpfr_ptr) 0); diff --git a/tests/tsin_cos.c b/tests/tsin_cos.c index 8608a8467..3822934af 100644 --- a/tests/tsin_cos.c +++ b/tests/tsin_cos.c @@ -650,7 +650,7 @@ coverage_01032011 (void) status_f = mpfr_sincos_fast (svalf, NULL, val, MPFR_RNDN); status = mpfr_sin_cos (sval, cval, val, MPFR_RNDN); - if (! mpfr_equal_p (svalf, sval) || SIGN (status_f) != SIGN (status)) + if (! mpfr_equal_p (svalf, sval) || VSIGN (status_f) != VSIGN (status)) { printf ("mpfr_sincos_fast differ from mpfr_sin_cos result:\n" " sin fast is "); diff --git a/tests/tsprintf.c b/tests/tsprintf.c index a2bb09c0b..8d9a49770 100644 --- a/tests/tsprintf.c +++ b/tests/tsprintf.c @@ -48,13 +48,15 @@ const char minf_uc_str[] = "-INF"; const char nan_str[] = "nan"; const char nan_uc_str[] = "NAN"; +int randsize; + /* 1. compare expected string with the string BUFFER returned by mpfr_sprintf(buffer, fmt, x) 2. then test mpfr_snprintf (buffer, p, fmt, x) with a random p. */ static int check_sprintf (const char *expected, const char *fmt, mpfr_srcptr x) { - int n0, n1, p; + int n0, n1; char buffer[BUF_SIZE]; /* test mpfr_sprintf */ @@ -68,18 +70,19 @@ check_sprintf (const char *expected, const char *fmt, mpfr_srcptr x) } /* test mpfr_snprintf */ - p = (int) (randlimb () % n0); - if (p == 0 && (randlimb () & 1) == 0) + randsize = (int) (randlimb () % (n0 + 3)) - 3; /* between -3 and n0 - 1 */ + if (randsize < 0) { n1 = mpfr_snprintf (NULL, 0, fmt, x); } else { - buffer[p] = 17; - n1 = mpfr_snprintf (buffer, p, fmt, x); - if (buffer[p] != 17) + buffer[randsize] = 17; + n1 = mpfr_snprintf (buffer, randsize, fmt, x); + if (buffer[randsize] != 17) { - printf ("Buffer overflow in mpfr_snprintf for p = %d!\n", p); + printf ("Buffer overflow in mpfr_snprintf for randsize = %d!\n", + randsize); exit (1); } } @@ -87,7 +90,7 @@ check_sprintf (const char *expected, const char *fmt, mpfr_srcptr x) { char format[1024]; printf ("Error in mpfr_snprintf (s, %d, \"%s\", x) return value\n", - p, fmt); + randsize, fmt); printf ("expected: %d\ngot: %d\n", n0, n1); strncpy (format, "x='", 1024); strncpy (format + 3, fmt, 1021); @@ -95,13 +98,14 @@ check_sprintf (const char *expected, const char *fmt, mpfr_srcptr x) mpfr_printf (format, x); exit (1); } - if ((p > 1 && strncmp (expected, buffer, p-1) != 0) - || (p == 1 && buffer[0] != '\0')) + if ((randsize > 1 && strncmp (expected, buffer, randsize - 1) != 0) + || (randsize == 1 && buffer[0] != '\0')) { char part_expected[BUF_SIZE]; - strncpy (part_expected, expected, p); - part_expected[p-1] = '\0'; - printf ("Error in mpfr_vsnprintf (s, %d, \"%s\", ...);\n", p, fmt); + strncpy (part_expected, expected, randsize); + part_expected[randsize - 1] = '\0'; + printf ("Error in mpfr_vsnprintf (s, %d, \"%s\", ...);\n", + randsize, fmt); printf ("expected: \"%s\"\ngot: \"%s\"\n", part_expected, buffer); exit (1); } @@ -114,63 +118,63 @@ check_sprintf (const char *expected, const char *fmt, mpfr_srcptr x) static int check_vsprintf (const char *expected, const char *fmt, ...) { - int n0, n1, p; + int n0, n1; char buffer[BUF_SIZE]; va_list ap0, ap1; - va_start (ap0, fmt); - va_start (ap1, fmt); + va_start (ap0, fmt); n0 = mpfr_vsprintf (buffer, fmt, ap0); + va_end (ap0); + if (strcmp (buffer, expected) != 0) { printf ("Error in mpfr_vsprintf (s, \"%s\", ...);\n", fmt); printf ("expected: \"%s\"\ngot: \"%s\"\n", expected, buffer); - - va_end (ap0); - va_end (ap1); exit (1); } - va_end (ap0); + + va_start (ap1, fmt); /* test mpfr_snprintf */ - p = (int) (randlimb () % n0); - if (p == 0 && (randlimb () & 1) == 0) + randsize = (int) (randlimb () % (n0 + 3)) - 3; /* between -3 and n0 - 1 */ + if (randsize < 0) { n1 = mpfr_vsnprintf (NULL, 0, fmt, ap1); } else { - buffer[p] = 17; - n1 = mpfr_vsnprintf (buffer, p, fmt, ap1); - if (buffer[p] != 17) + buffer[randsize] = 17; + n1 = mpfr_vsnprintf (buffer, randsize, fmt, ap1); + if (buffer[randsize] != 17) { - printf ("Buffer overflow in mpfr_vsnprintf for p = %d!\n", p); + printf ("Buffer overflow in mpfr_vsnprintf for randsize = %d!\n", + randsize); exit (1); } } + + va_end (ap1); + if (n0 != n1) { printf ("Error in mpfr_vsnprintf (s, %d, \"%s\", ...) return value\n", - p, fmt); + randsize, fmt); printf ("expected: %d\ngot: %d\n", n0, n1); - - va_end (ap1); exit (1); } - if ((p > 1 && strncmp (expected, buffer, p-1) != 0) - || (p == 1 && buffer[0] != '\0')) + if ((randsize > 1 && strncmp (expected, buffer, randsize - 1) != 0) + || (randsize == 1 && buffer[0] != '\0')) { char part_expected[BUF_SIZE]; - strncpy (part_expected, expected, p); - part_expected[p-1] = '\0'; - printf ("Error in mpfr_vsnprintf (s, %d, \"%s\", ...);\n", p, fmt); - printf ("expected: \"%s\"\ngot: \"%s\"\n", part_expected, buffer); - va_end (ap1); + strncpy (part_expected, expected, randsize); + part_expected[randsize - 1] = '\0'; + printf ("Error in mpfr_vsnprintf (s, %d, \"%s\", ...);\n", + randsize, fmt); + printf ("expected: \"%s\"\ngot: \"%s\"\n", part_expected, buffer); exit (1); } - va_end (ap1); return n0; } @@ -807,6 +811,7 @@ mixed (void) mpz_t mpz; mpfr_t x; mpfr_rnd_t rnd; + int k; mpf_init (mpf); mpf_set_ui (mpf, 40); @@ -826,14 +831,26 @@ mixed (void) x); check_vsprintf ("-12345678.9, 121", "%.1Rf, %i", x, i); check_vsprintf ("-12345678, 1e240/45b352", "%.0R*f, %Qx", MPFR_RNDZ, x, mpq); - n1 = check_vsprintf ("121, -12345678.875000000000, 1.290323", "%i, %.*Rf, %Ff%n", - i, 12, x, mpf, &n2); - if (n1 != n2) + + /* TODO: Systematically test with and without %n in check_vsprintf? */ + /* Do the test several times due to random parameters in check_vsprintf + and the use of %n. In r11501, n2 is incorrect (seems random) when + randsize <= 0, i.e. when the size argument of mpfr_vsnprintf is 0. */ + for (k = 0; k < 30; k++) { - printf ("error in number of characters written by mpfr_vsprintf\n"); - printf ("expected: %d\n", n2); - printf (" got: %d\n", n1); - exit (1); + n2 = -17; + /* If this value is obtained for n2 after the check_vsprintf call below, + this probably means that n2 has not been written as expected. */ + n1 = check_vsprintf ("121, -12345678.875000000000, 1.290323", + "%i, %.*Rf, %Ff%n", i, 12, x, mpf, &n2); + if (n1 != n2) + { + printf ("error in number of characters written by mpfr_vsprintf" + " for k = %d, randsize = %d\n", k, randsize); + printf ("expected: %d\n", n2); + printf (" got: %d\n", n1); + exit (1); + } } #ifdef PRINTF_L @@ -883,16 +900,24 @@ locale_da_DK (void) check_sprintf (" 000000018.993.474,61279296875", "%' 030.19RG", x); check_sprintf (" 00000000000018.993.474,612793", "%' 030RF", x); - mpfr_set_ui (x, 50, MPFR_RNDN); +#define T1 "000" +#define T2 ".000" +#define S1 T1 T1 T1 T1 T1 T1 T1 T1 T1 T1 T1 T1 T1 T1 T1 T1 +#define S2 T2 T2 T2 T2 T2 T2 T2 T2 T2 T2 T2 T2 T2 T2 T2 T2 "," + + mpfr_set_ui (x, 48, MPFR_RNDN); mpfr_exp10 (x, x, MPFR_RNDN); - check_sprintf ("100000000000000000000000000000000000000000000000000", "%.0Rf", - x); - check_sprintf - ("100.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000,", - "%'#.0Rf", x); - check_sprintf - ("100.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000,0000", - "%'.4Rf", x); + check_sprintf ("1" S1, "%.0Rf", x); + check_sprintf ("1" S2, "%'#.0Rf", x); + check_sprintf ("1" S2 "0000", "%'.4Rf", x); + mpfr_mul_ui (x, x, 10, MPFR_RNDN); + check_sprintf ("10" S1, "%.0Rf", x); + check_sprintf ("10" S2, "%'#.0Rf", x); + check_sprintf ("10" S2 "0000", "%'.4Rf", x); + mpfr_mul_ui (x, x, 10, MPFR_RNDN); + check_sprintf ("100" S1, "%.0Rf", x); + check_sprintf ("100" S2, "%'#.0Rf", x); + check_sprintf ("100" S2 "0000", "%'.4Rf", x); mpfr_clear (x); return 0; @@ -1369,37 +1394,73 @@ snprintf_size (void) mpfr_clear (x); } +/* With r11516, n2 gets a random value for i = 0 only! + valgrind detects a problem for "nchar = buf.curr - buf.start;" + in the spec.spec == 'n' case. Indeed, there is no buffer when + size is 0. */ +static void +percent_n (void) +{ + int err = 0, i, j; + + for (i = 0; i < 24; i++) + for (j = 0; j < 3; j++) + { + volatile int n1, n2; + char buffer[64]; + + memset (buffer, 0, 64); + n2 = -17; + n1 = mpfr_snprintf (buffer, i % 8, "%d%n", 123, &n2); + if (n1 != 3 || n2 != 3) + { + printf ("Error 1 in percent_n: i = %d, n1 = %d, n2 = %d\n", + i, n1, n2); + err = 1; + } + } + + if (err) + exit (1); +} + int main (int argc, char **argv) { - char *locale; + int k; tests_start_mpfr (); #if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE) /* currently, we just check with 'C' locale */ - locale = setlocale (LC_ALL, "C"); + setlocale (LC_ALL, "C"); #endif bug20111102 (); - native_types (); - hexadecimal (); - binary (); - decimal (); - mixed (); - check_emax (); - check_emin (); - test20161214 (); - bug21056 (); - snprintf_size (); + + for (k = 0; k < 40; k++) + { + native_types (); + hexadecimal (); + binary (); + decimal (); #if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE) #if MPFR_LCONV_DPTS - locale_da_DK (); + locale_da_DK (); /* Avoid a warning by doing the setlocale outside of this #if */ #endif - setlocale (LC_ALL, locale); + setlocale (LC_ALL, "C"); #endif + } + + check_emax (); + check_emin (); + test20161214 (); + bug21056 (); + snprintf_size (); + percent_n (); + mixed (); if (getenv ("MPFR_CHECK_LIBC_PRINTF")) { diff --git a/tests/tstckintc.c b/tests/tstckintc.c index b5d4ebe56..998680b3e 100644 --- a/tests/tstckintc.c +++ b/tests/tstckintc.c @@ -193,24 +193,24 @@ test_nan_inf_zero (void) sign = 1; mpfr_set_inf (val, sign); kind = (mpfr_custom_get_kind) (val); - if ((ABS (kind) != MPFR_INF_KIND) || (SIGN (kind) != SIGN (sign))) + if ((ABS (kind) != MPFR_INF_KIND) || (VSIGN (kind) != VSIGN (sign))) { printf ("mpfr_custom_get_kind error: "); mpfr_dump (val); printf (" is kind %d instead of %d\n", kind, (int) MPFR_INF_KIND); - printf (" have sign %d instead of %d\n", SIGN (kind), SIGN (sign)); + printf (" have sign %d instead of %d\n", VSIGN (kind), VSIGN (sign)); exit (1); } sign = -1; mpfr_set_zero (val, sign); kind = (mpfr_custom_get_kind) (val); - if ((ABS (kind) != MPFR_ZERO_KIND) || (SIGN (kind) != SIGN (sign))) + if ((ABS (kind) != MPFR_ZERO_KIND) || (VSIGN (kind) != VSIGN (sign))) { printf ("mpfr_custom_get_kind error: "); mpfr_dump (val); printf (" is kind %d instead of %d\n", kind, (int) MPFR_ZERO_KIND); - printf (" have sign %d instead of %d\n", SIGN (kind), SIGN (sign)); + printf (" have sign %d instead of %d\n", VSIGN (kind), VSIGN (sign)); exit (1); } diff --git a/tests/tstrtofr.c b/tests/tstrtofr.c index ab5ffd46d..7fe388ec3 100644 --- a/tests/tstrtofr.c +++ b/tests/tstrtofr.c @@ -1162,9 +1162,9 @@ bug20120829 (void) mpfr_rnd_t rnd = (mpfr_rnd_t) r; inex1 = mpfr_exp10 (x1, e, rnd); - inex1 = SIGN (inex1); + inex1 = VSIGN (inex1); inex2 = mpfr_strtofr (x2, s, NULL, 0, rnd); - inex2 = SIGN (inex2); + inex2 = VSIGN (inex2); /* On 32-bit machines, for i = 7, r8389, r8391 and r8394 do: strtofr.c:...: MPFR assertion failed: cy == 0 r8396 is OK. diff --git a/tests/tversion.c b/tests/tversion.c index 12fb18632..ee26c0ea4 100644 --- a/tests/tversion.c +++ b/tests/tversion.c @@ -240,6 +240,12 @@ main (void) #else "no" #endif + ", IEEE floats = " +#if _MPFR_IEEE_FLOATS + "yes" +#else + "no" +#endif "\n"); printf ("[tversion] gmp_printf: hhd = " diff --git a/tools/mbench/mfv5.h b/tools/mbench/mfv5.h index b47c5a735..ad4c32d82 100644 --- a/tools/mbench/mfv5.h +++ b/tools/mbench/mfv5.h @@ -87,7 +87,7 @@ class timming { timming (unsigned long s) : size (s) { besttime = new unsigned long long[size]; for (unsigned long i = 0 ; i < size ; i++) - besttime[i] = 0xFFFFFFFFFFFFFFFLL; + besttime[i] = 0xFFFFFFFFFFFFFFFFLL; } ~timming () { @@ -107,7 +107,7 @@ class timming { void print (const char *name, const option_test &opt) { unsigned long long min, max, moy; unsigned long imin = 0, imax = 0; - min = 0xFFFFFFFFFFFFFFFLL; + min = 0xFFFFFFFFFFFFFFFFLL; max = moy = 0; for(unsigned long i = 0 ; i < (size-1) ; i++) { if (besttime[i] < min) diff --git a/tools/mbench/timp.h b/tools/mbench/timp.h index 858f803b4..6239a8639 100644 --- a/tools/mbench/timp.h +++ b/tools/mbench/timp.h @@ -147,10 +147,10 @@ static unsigned long long int timp_overhead = 0; #define TIMP_NUM_TRY 4327 #define TIMP_MAX_WAIT_FOR_MEASURE 10000000ULL -#define TIMP_MEASURE(CODE) \ +#define TIMP_MEASURE_AUX(CODE) \ ({ \ volatile unsigned long long int num_cycle, num_cycle2; \ - unsigned long long min_num_cycle, start_num_cycle; \ + unsigned long long int min_num_cycle, start_num_cycle; \ int _i; \ timp_rdtsc_before (start_num_cycle); \ min_num_cycle = 0xFFFFFFFFFFFFFFFFLL; \ @@ -158,15 +158,27 @@ static unsigned long long int timp_overhead = 0; timp_rdtsc_before(num_cycle); \ CODE; \ timp_rdtsc_after(num_cycle2); \ - num_cycle = num_cycle2 - num_cycle; \ + num_cycle = num_cycle2 < num_cycle ? 0 /* shouldn't happen */ \ + : num_cycle2 - num_cycle; \ if (num_cycle < min_num_cycle) \ min_num_cycle = num_cycle; \ if (num_cycle2 - start_num_cycle > TIMP_MAX_WAIT_FOR_MEASURE) \ break; \ } \ - min_num_cycle - timp_overhead; }) + min_num_cycle < timp_overhead ? 0 : min_num_cycle - timp_overhead; }) + +/* If the return value of TIMP_MEASURE_AUX() is 0, this probably means + that timp_overhead was too large and incorrect; this can occur just + after starting the process. In this case, TIMP_OVERHEAD() is called + again to recompute timp_overhead and the timing is redone. */ +#define TIMP_MEASURE(CODE) \ + ({ \ + unsigned long long int _m; \ + while ((_m = TIMP_MEASURE_AUX(CODE)) == 0) \ + TIMP_OVERHEAD(); \ + _m; }) #define TIMP_OVERHEAD() \ - (timp_overhead = 0, timp_overhead = TIMP_MEASURE((void) 0) ) + (timp_overhead = 0, timp_overhead = TIMP_MEASURE_AUX((void) 0) ) #endif /* __TIMP__H__ */ diff --git a/tools/mpfrlint b/tools/mpfrlint index fdc19fc5b..91a75da94 100755 --- a/tools/mpfrlint +++ b/tools/mpfrlint @@ -102,6 +102,32 @@ fi ############################################################################ +# Note: In the source, ignore everything related to mini-gmp. +srctests=({src,tests}/**/*.[ch]~*mini-gmp.*) +#srctests=(`find src tests -name '*.[ch]' ! -name '*mini-gmp.*'`) + +# Detect the definition of reserved macro names. +# +# See ISO C 7.1.3 (Reserved identifiers) and 7.31 (Future library directions). +# The definition of a reserved identifier is undefined behavior +# (this includes the future library directions). +# +# Note: The following check may have false positives in some cases, +# but this may also correspond to bad coding, in particular because +# code moves. We assume that if a header is used somewhere, it may +# be used everywhere in the MPFR code. This particularly concerns +# macros defined via mpfr-impl.h or mpfr-test.h, which are included +# in almost every tests. +# +# The case of EXP in src/mpfr-gmp.h is not really fixable due to the +# possible use of gmp-impl.h, but we should make sure that <errno.h> +# is never included in this case (see comment in the code). +names='E[0-9A-Z]|FE_[A-Z]|LC_[A-Z]|(PRI|SCN)[Xa-z]|SIG_?[A-Z]|TIME_[A-Z]' +msg='ISO C 7.1.3 (Reserved identifiers) and 7.31 (Future library directions).' +grep -E "# *define ($names)" $srctests | \ + grep -v 'src/mpfr-gmp.h:#define EXP(' | \ + err-if-output --msg="$msg" "reserved identifiers (macro names)" cat + # Detect the possible use of forbidden macros in mpfr.h, such as those # starting with "HAVE_" or "WANT_". Public macros defined by MPFR must # start with "MPFR_". @@ -137,10 +163,6 @@ grconf '="`' grconf '[^a-z][ef]?grep[^a-z]' grconf '[^a-z]sed[^a-z]' -# Note: In the source, ignore everything related to mini-gmp. -srctests=({src,tests}/**/*.[ch]~*mini-gmp.*) -#srctests=(`find src tests -name '*.[ch]' ! -name '*mini-gmp.*'`) - err-if-output --msg="Use GMP_NUMB_BITS instead." \ -t "GMP_LIMB_BITS" grep GMP_LIMB_BITS $srctests |