xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tinternals.c (revision 7788a0781fe6ff2cce37368b4578a7ade0850cb1)
1 /* tinternals -- Test for internals.
2 
3 Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4 Contributed by the Arenaire and Cacao projects, INRIA.
5 
6 This file is part of the GNU MPFR Library.
7 
8 The GNU MPFR Library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
12 
13 The GNU MPFR Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16 License for more details.
17 
18 You should have received a copy of the GNU Lesser General Public License
19 along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
20 http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 
26 #define MPFR_NEED_LONGLONG_H
27 #include "mpfr-test.h"
28 
29 static void
30 test_int_ceil_log2 (void)
31 {
32   int i;
33   int val[16] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 };
34 
35   for (i = 1; i < 17; i++)
36     {
37       if (MPFR_INT_CEIL_LOG2 (i) != val[i-1])
38         {
39           printf ("Error 1 in test_int_ceil_log2 for i = %d\n", i);
40           exit (1);
41         }
42       if (MPFR_INT_CEIL_LOG2 (i) != __gmpfr_int_ceil_log2 (i))
43         {
44           printf ("Error 2 in test_int_ceil_log2 for i = %d\n", i);
45           exit (1);
46         }
47     }
48 }
49 
50 static void
51 test_round_near_x (void)
52 {
53   mpfr_t x, y, z, eps;
54   mpfr_exp_t e;
55   int failures = 0, mx, neg, err, dir, r, inex, inex2;
56   char buffer[7], *p;
57 
58   mpfr_inits (x, y, z, eps, (mpfr_ptr) 0);
59   mpfr_set_prec (x, 5);
60   mpfr_set_prec (y, 3);
61   mpfr_set_prec (z, 3);
62   mpfr_set_prec (eps, 2);
63   mpfr_set_ui_2exp (eps, 1, -32, MPFR_RNDN);
64 
65   for (mx = 16; mx < 32; mx++)
66     {
67       mpfr_set_ui_2exp (x, mx, -2, MPFR_RNDN);
68       for (p = buffer, neg = 0;
69            neg <= 1;
70            mpfr_neg (x, x, MPFR_RNDN), p++, neg++)
71         for (err = 2; err <= 6; err++)
72           for (dir = 0; dir <= 1; dir++)
73             RND_LOOP(r)
74               {
75                 inex = mpfr_round_near_x (y, x, err, dir, (mpfr_rnd_t) r);
76 
77                 if (inex == 0 && err < 6)
78                   {
79                     /* The test is more restrictive than necessary.
80                        So, no failure in this case. */
81                     continue;
82                   }
83 
84                 inex2 = ((dir ^ neg) ? mpfr_add : mpfr_sub)
85                   (z, x, eps, (mpfr_rnd_t) r);
86                 if (inex * inex2 <= 0)
87                   printf ("Bad return value (%d instead of %d) for:\n",
88                           inex, inex2);
89                 else if (mpfr_equal_p (y, z))
90                   continue;  /* correct inex and y */
91                 else
92                   {
93                     printf ("Bad MPFR value (should have got ");
94                     mpfr_out_str (stdout, 2, 3, z, MPFR_RNDZ);
95                     printf (") for:\n");
96                   }
97 
98                 if (!mpfr_get_str (buffer, &e, 2, 5, x, MPFR_RNDZ) || e != 3)
99                   {
100                     printf ("mpfr_get_str failed in test_round_near_x\n");
101                     exit (1);
102                   }
103                 printf ("x = %c%c%c%c.%c%c, ", neg ? '-' : '+',
104                         p[0], p[1], p[2], p[3], p[4]);
105                 printf ("err = %d, dir = %d, r = %s --> inex = %2d",
106                         err, dir, mpfr_print_rnd_mode ((mpfr_rnd_t) r), inex);
107                 if (inex != 0)
108                   {
109                     printf (", y = ");
110                     mpfr_out_str (stdout, 2, 3, y, MPFR_RNDZ);
111                   }
112                 printf ("\n");
113                 if (inex == 0)
114                   printf ("Rounding was possible!\n");
115                 if (++failures == 10)  /* show at most 10 failures */
116                   exit (1);
117               }
118     }
119 
120   if (failures)
121     exit (1);
122 
123   mpfr_clears (x, y, z, eps, (mpfr_ptr) 0);
124 }
125 
126 int
127 main (int argc, char **argv)
128 {
129   tests_start_mpfr ();
130 
131   /* The tested function and macro exist in MPFR 2.2.0, but with a
132      different (incorrect, but with no effect in 2.2.0) behavior. */
133 #if MPFR_VERSION >= MPFR_VERSION_NUM(2,3,0)
134   test_int_ceil_log2 ();
135 #endif
136 
137   test_round_near_x ();
138 
139   tests_end_mpfr ();
140   return 0;
141 }
142