xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tui_div.c (revision 1897181a7231d5fc7ab48994d1447fcbc4e13a49)
1 /* Test file for mpfr_ui_div.
2 
3 Copyright 2000, 2001, 2002, 2003, 2004, 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 #include "mpfr-test.h"
27 
28 /* checks that y/x gives the right result with 53 bits of precision */
29 static void
30 check (unsigned long y, const char *xs, mpfr_rnd_t rnd_mode, const char *zs)
31 {
32   mpfr_t xx, zz;
33 
34   mpfr_inits2 (53, xx, zz, (mpfr_ptr) 0);
35   mpfr_set_str1 (xx, xs);
36   mpfr_ui_div (zz, y, xx, rnd_mode);
37   if (mpfr_cmp_str1(zz, zs))
38     {
39       printf ("expected quotient is %s, got ", zs);
40       mpfr_out_str (stdout, 10, 0, zz, MPFR_RNDN);
41       printf ("mpfr_ui_div failed for y=%lu x=%s with rnd_mode=%s\n",
42               y, xs, mpfr_print_rnd_mode (rnd_mode));
43       exit (1);
44     }
45   mpfr_clears (xx, zz, (mpfr_ptr) 0);
46 }
47 
48 static void
49 check_inexact (void)
50 {
51   mpfr_t x, y, z;
52   mpfr_prec_t px, py;
53   int inexact, cmp;
54   unsigned long int u;
55   int rnd;
56 
57   mpfr_init (x);
58   mpfr_init (y);
59   mpfr_init (z);
60 
61   for (px=2; px<300; px++)
62     {
63       mpfr_set_prec (x, px);
64       do
65         {
66           mpfr_urandomb (x, RANDS);
67         }
68       while (mpfr_cmp_ui (x, 0) == 0);
69       u = randlimb ();
70       for (py=2; py<300; py++)
71         {
72           mpfr_set_prec (y, py);
73           mpfr_set_prec (z, py + px);
74           for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
75             {
76               inexact = mpfr_ui_div (y, u, x, (mpfr_rnd_t) rnd);
77               if (mpfr_mul (z, y, x, (mpfr_rnd_t) rnd))
78                 {
79                   printf ("z <- y * x should be exact\n");
80                   exit (1);
81                 }
82               cmp = mpfr_cmp_ui (z, u);
83               if (((inexact == 0) && (cmp != 0)) ||
84                   ((inexact > 0) && (cmp <= 0)) ||
85                   ((inexact < 0) && (cmp >= 0)))
86                 {
87                   printf ("Wrong inexact flag for u=%lu, rnd=%s\n",
88                           u, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
89                   printf ("expected %d, got %d\n", cmp, inexact);
90                   printf ("x="); mpfr_print_binary (x); puts ("");
91                   printf ("y="); mpfr_print_binary (y); puts ("");
92                   printf ("y*x="); mpfr_print_binary (z); puts ("");
93                   exit (1);
94                 }
95             }
96         }
97     }
98 
99   mpfr_clear (x);
100   mpfr_clear (y);
101   mpfr_clear (z);
102 }
103 
104 static void
105 check_nan (void)
106 {
107   mpfr_t  d, q;
108 
109   mpfr_init2 (d, 100L);
110   mpfr_init2 (q, 100L);
111 
112   /* 1/+inf == 0 */
113   MPFR_SET_INF (d);
114   MPFR_SET_POS (d);
115   MPFR_ASSERTN (mpfr_ui_div (q, 1L, d, MPFR_RNDZ) == 0); /* exact */
116   MPFR_ASSERTN (mpfr_number_p (q));
117   MPFR_ASSERTN (mpfr_sgn (q) == 0);
118 
119   /* 1/-inf == -0 */
120   MPFR_SET_INF (d);
121   MPFR_SET_NEG (d);
122   MPFR_ASSERTN (mpfr_ui_div (q, 1L, d, MPFR_RNDZ) == 0); /* exact */
123   MPFR_ASSERTN (mpfr_number_p (q));
124   MPFR_ASSERTN (mpfr_sgn (q) == 0);
125 
126   /* 1/nan == nan */
127   MPFR_SET_NAN (d);
128   MPFR_ASSERTN (mpfr_ui_div (q, 1L, d, MPFR_RNDZ) == 0); /* exact */
129   MPFR_ASSERTN (mpfr_nan_p (q));
130 
131   /* 0/0 == nan */
132   mpfr_set_ui (d, 0L, MPFR_RNDN);
133   MPFR_ASSERTN (mpfr_ui_div (q, 0L, d, MPFR_RNDZ) == 0); /* exact */
134   MPFR_ASSERTN (mpfr_nan_p (q));
135 
136   /* 1/+0 = +inf */
137   mpfr_set_ui (d, 0L, MPFR_RNDN);
138   MPFR_ASSERTN (mpfr_ui_div (q, 1L, d, MPFR_RNDZ) == 0); /* exact */
139   MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0);
140 
141   /* 1/-0 = -inf */
142   mpfr_set_ui (d, 0L, MPFR_RNDN);
143   mpfr_neg (d, d, MPFR_RNDN);
144   MPFR_ASSERTN (mpfr_ui_div (q, 1L, d, MPFR_RNDZ) == 0); /* exact */
145   MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0);
146 
147   /* 0/1 = +0 */
148   mpfr_set_ui (d, 1L, MPFR_RNDN);
149   MPFR_ASSERTN (mpfr_ui_div (q, 0L, d, MPFR_RNDZ) == 0); /* exact */
150   MPFR_ASSERTN (mpfr_cmp_ui (q, 0) == 0 && MPFR_IS_POS (q));
151 
152   /* 0/-1 = -0 */
153   mpfr_set_si (d, -1, MPFR_RNDN);
154   MPFR_ASSERTN (mpfr_ui_div (q, 0L, d, MPFR_RNDZ) == 0); /* exact */
155   MPFR_ASSERTN (mpfr_cmp_ui (q, 0) == 0 && MPFR_IS_NEG (q));
156 
157   mpfr_clear (d);
158   mpfr_clear (q);
159 }
160 
161 static int
162 mpfr_inv (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t r)
163 {
164   return mpfr_ui_div (y, 1, x, r);
165 }
166 
167 int
168 main (int argc, char *argv[])
169 {
170   tests_start_mpfr ();
171 
172   check_nan ();
173   check_inexact ();
174   check(948002822, "1.22191250737771397120e+20", MPFR_RNDN,
175         "7.758352715731357946e-12");
176   check(1976245324, "1.25296395864546893357e+232", MPFR_RNDZ,
177         "1.5772563211925444801e-223");
178   check(740454110, "2.11496253355831863313e+183", MPFR_RNDZ,
179         "3.5010270784996976041e-175");
180   check(1690540942, "1.28278599852446657468e-276", MPFR_RNDU,
181         "1.3178666932321966062e285");
182   check(1476599377, "-2.14191393656148625995e+305", MPFR_RNDD,
183         "-6.8938315017943889615e-297");
184 
185   /* inv is for 1/x */
186   data_check ("data/inv", mpfr_inv, "mpfr_ui_div(1,x)");
187 
188   tests_end_mpfr ();
189   return 0;
190 }
191