1
/* Test file for mpfr_sub_ui
3
Copyright 2000, 2001, 2002 Free Software Foundation.
5
This file is part of the MPFR Library.
7
The MPFR Library is free software; you can redistribute it and/or modify
8
it under the terms of the GNU Lesser General Public License as published by
9
the Free Software Foundation; either version 2.1 of the License, or (at your
10
option) any later version.
12
The MPFR Library is distributed in the hope that it will be useful, but
13
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15
License for more details.
17
You should have received a copy of the GNU Lesser General Public License
18
along with the MPFR Library; see the file COPYING.LIB. If not, write to
19
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20
MA 02111-1307, USA. */
28
#include "mpfr-impl.h"
29
#include "mpfr-test.h"
31
void check_two_sum _PROTO ((mp_prec_t));
32
void check3 _PROTO ((double, unsigned long, mp_rnd_t, double));
34
#define check(x,y,r) check3(x,y,r,0.0)
36
/* checks that x+y gives the same results in double
37
and with mpfr with 53 bits of precision */
39
check3 (double x, unsigned long y, mp_rnd_t rnd_mode, double z1)
46
mpfr_set_prec(xx, 53);
47
mpfr_set_prec(zz, 53);
48
mpfr_set_d(xx, x, rnd_mode);
49
mpfr_sub_ui(zz, xx, y, rnd_mode);
50
#ifdef MPFR_HAVE_FESETROUND
51
mpfr_set_machine_rnd_mode(rnd_mode);
53
if (z1==0.0) z1 = x-y;
54
z2 = mpfr_get_d1 (zz);
55
if (z1!=z2 && !(isnan(z1) && isnan(z2))) {
56
printf("expected sum is %1.20e, got %1.20e\n",z1,z2);
57
printf("mpfr_sub_ui failed for x=%1.20e y=%lu with rnd_mode=%s\n",
58
x, y, mpfr_print_rnd_mode(rnd_mode));
65
/* FastTwoSum: if EXP(x) >= EXP(y), u = o(x+y), v = o(u-x), w = o(y-v),
67
thus if u = o(y-x), v = o(u+x), w = o(v-y), then y-x = u-w */
69
check_two_sum (mp_prec_t p)
86
rnd = LONG_RAND() % 4;
88
inexact = mpfr_sub_ui (u, y, x, GMP_RNDN);
89
mpfr_add_ui (v, u, x, GMP_RNDN);
90
mpfr_sub (w, v, y, GMP_RNDN);
91
/* as u - (y-x) = w, we should have inexact and w of same sign */
92
if (((inexact == 0) && mpfr_cmp_ui (w, 0)) ||
93
((inexact > 0) && (mpfr_cmp_ui (w, 0) <= 0)) ||
94
((inexact < 0) && (mpfr_cmp_ui (w, 0) >= 0)))
96
fprintf (stderr, "Wrong inexact flag for prec=%u, rnd=%s\n", (unsigned)p,
97
mpfr_print_rnd_mode (rnd));
99
printf ("y="); mpfr_print_binary(y); putchar('\n');
100
printf ("u="); mpfr_print_binary(u); putchar('\n');
101
printf ("v="); mpfr_print_binary(v); putchar('\n');
102
printf ("w="); mpfr_print_binary(w); putchar('\n');
103
printf ("inexact = %d\n", inexact);
113
main (int argc, char *argv[])
117
#ifdef MPFR_HAVE_FESETROUND
118
double x; unsigned long y, N; int i,rnd_mode,rnd;
122
SEED_RAND (time(NULL));
123
N = (argc<2) ? 1000000 : atoi(argv[1]);
124
rnd_mode = (argc<3) ? -1 : atoi(argv[2]);
125
for (i=0;i<1000000;i++) {
128
if (ABS(x)>2.2e-307 && x+y<1.7e+308 && x+y>-1.7e308) {
129
/* avoid denormalized numbers and overflows */
130
rnd = (rnd_mode==-1) ? LONG_RAND()%4 : rnd_mode;
136
for (p=2; p<200; p++)
137
for (k=0; k<200; k++)
140
check3 (0.9999999999, 1, GMP_RNDN, -56295.0 / 562949953421312.0);
142
check3 (DBL_NAN, 1, GMP_RNDN, DBL_NAN);
143
check3 (DBL_POS_INF, 1, GMP_RNDN, DBL_POS_INF);
144
check3 (DBL_NEG_INF, 1, GMP_RNDN, DBL_NEG_INF);