xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tdiv_ui.c (revision 92e958de60c71aa0f2452bd7074cbb006fe6546b)
1 /* Test file for mpfr_div_ui.
2 
3 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
4 Contributed by the AriC and Caramel 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 #include <float.h>
26 
27 #include "mpfr-test.h"
28 
29 static void
30 check (const char *ds, unsigned long u, mpfr_rnd_t rnd, const char *es)
31 {
32   mpfr_t x, y;
33 
34   mpfr_init2 (x, 53);
35   mpfr_init2 (y, 53);
36   mpfr_set_str1 (x, ds);
37   mpfr_div_ui (y, x, u, rnd);
38   if (mpfr_cmp_str1 (y, es))
39     {
40       printf ("mpfr_div_ui failed for x=%s, u=%lu, rnd=%s\n", ds, u,
41               mpfr_print_rnd_mode (rnd));
42       printf ("expected result is %s, got", es);
43       mpfr_out_str(stdout, 10, 0, y, MPFR_RNDN);
44       exit (1);
45     }
46   mpfr_clear (x);
47   mpfr_clear (y);
48 }
49 
50 static void
51 special (void)
52 {
53   mpfr_t x, y;
54   unsigned xprec, yprec;
55 
56   mpfr_init (x);
57   mpfr_init (y);
58 
59   mpfr_set_prec (x, 32);
60   mpfr_set_prec (y, 32);
61   mpfr_set_ui (x, 1, MPFR_RNDN);
62   mpfr_div_ui (y, x, 3, MPFR_RNDN);
63 
64   mpfr_set_prec (x, 100);
65   mpfr_set_prec (y, 100);
66   mpfr_urandomb (x, RANDS);
67   mpfr_div_ui (y, x, 123456, MPFR_RNDN);
68   mpfr_set_ui (x, 0, MPFR_RNDN);
69   mpfr_div_ui (y, x, 123456789, MPFR_RNDN);
70   if (mpfr_cmp_ui (y, 0))
71     {
72       printf ("mpfr_div_ui gives non-zero for 0/ui\n");
73       exit (1);
74     }
75 
76   /* bug found by Norbert Mueller, 21 Aug 2001 */
77   mpfr_set_prec (x, 110);
78   mpfr_set_prec (y, 60);
79   mpfr_set_str_binary (x, "0.110101110011111110011111001110011001110111000000111110001000111011000011E-44");
80   mpfr_div_ui (y, x, 17, MPFR_RNDN);
81   mpfr_set_str_binary (x, "0.11001010100101100011101110000001100001010110101001010011011E-48");
82   if (mpfr_cmp (x, y))
83     {
84       printf ("Error in x/17 for x=1/16!\n");
85       printf ("Expected ");
86       mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
87       printf ("\nGot      ");
88       mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
89       printf ("\n");
90       exit (1);
91     }
92 
93   /* corner case */
94   mpfr_set_prec (x, 2 * mp_bits_per_limb);
95   mpfr_set_prec (y, 2);
96   mpfr_set_ui (x, 4, MPFR_RNDN);
97   mpfr_nextabove (x);
98   mpfr_div_ui (y, x, 2, MPFR_RNDN); /* exactly in the middle */
99   MPFR_ASSERTN(mpfr_cmp_ui (y, 2) == 0);
100 
101   mpfr_set_prec (x, 3 * mp_bits_per_limb);
102   mpfr_set_prec (y, 2);
103   mpfr_set_ui (x, 2, MPFR_RNDN);
104   mpfr_nextabove (x);
105   mpfr_div_ui (y, x, 2, MPFR_RNDN);
106   MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0);
107 
108   mpfr_set_prec (x, 3 * mp_bits_per_limb);
109   mpfr_set_prec (y, 2);
110   mpfr_set_si (x, -4, MPFR_RNDN);
111   mpfr_nextbelow (x);
112   mpfr_div_ui (y, x, 2, MPFR_RNDD);
113   MPFR_ASSERTN(mpfr_cmp_si (y, -3) == 0);
114 
115   for (xprec = 53; xprec <= 128; xprec++)
116     {
117       mpfr_set_prec (x, xprec);
118       mpfr_set_str_binary (x, "0.1100100100001111110011111000000011011100001100110111E2");
119       for (yprec = 53; yprec <= 128; yprec++)
120         {
121           mpfr_set_prec (y, yprec);
122           mpfr_div_ui (y, x, 1, MPFR_RNDN);
123           if (mpfr_cmp(x,y))
124             {
125               printf ("division by 1.0 fails for xprec=%u, yprec=%u\n", xprec, yprec);
126               printf ("expected "); mpfr_print_binary (x); puts ("");
127               printf ("got      "); mpfr_print_binary (y); puts ("");
128               exit (1);
129             }
130         }
131     }
132 
133   /* Bug reported by Mark Dickinson, 6 Nov 2007 */
134   mpfr_set_si (x, 0, MPFR_RNDN);
135   mpfr_set_si (y, -1, MPFR_RNDN);
136   mpfr_div_ui (y, x, 4, MPFR_RNDN);
137   MPFR_ASSERTN(MPFR_IS_ZERO(y) && MPFR_IS_POS(y));
138 
139   mpfr_clear (x);
140   mpfr_clear (y);
141 }
142 
143 static void
144 check_inexact (void)
145 {
146   mpfr_t x, y, z;
147   mpfr_prec_t px, py;
148   int inexact, cmp;
149   unsigned long int u;
150   int rnd;
151 
152   mpfr_init (x);
153   mpfr_init (y);
154   mpfr_init (z);
155 
156   for (px=2; px<300; px++)
157     {
158       mpfr_set_prec (x, px);
159       mpfr_urandomb (x, RANDS);
160       do
161         {
162           u = randlimb ();
163         }
164       while (u == 0);
165       for (py=2; py<300; py++)
166         {
167           mpfr_set_prec (y, py);
168           mpfr_set_prec (z, py + mp_bits_per_limb);
169           for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
170             {
171               inexact = mpfr_div_ui (y, x, u, (mpfr_rnd_t) rnd);
172               if (mpfr_mul_ui (z, y, u, (mpfr_rnd_t) rnd))
173                 {
174                   printf ("z <- y * u should be exact for u=%lu\n", u);
175                   printf ("y="); mpfr_print_binary (y); puts ("");
176                   printf ("z="); mpfr_print_binary (z); puts ("");
177                   exit (1);
178                 }
179               cmp = mpfr_cmp (z, x);
180               if (((inexact == 0) && (cmp != 0)) ||
181                   ((inexact > 0) && (cmp <= 0)) ||
182                   ((inexact < 0) && (cmp >= 0)))
183                 {
184                   printf ("Wrong inexact flag for u=%lu, rnd=%s\n", u,
185                           mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
186                   printf ("x="); mpfr_print_binary (x); puts ("");
187                   printf ("y="); mpfr_print_binary (y); puts ("");
188                   exit (1);
189                 }
190             }
191         }
192     }
193 
194   mpfr_clear (x);
195   mpfr_clear (y);
196   mpfr_clear (z);
197 }
198 
199 #define TEST_FUNCTION mpfr_div_ui
200 #define INTEGER_TYPE  unsigned long
201 #define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS)
202 #include "tgeneric_ui.c"
203 
204 int
205 main (int argc, char **argv)
206 {
207   mpfr_t x;
208 
209   tests_start_mpfr ();
210 
211   special ();
212 
213   check_inexact ();
214 
215   check("1.0", 3, MPFR_RNDN, "3.3333333333333331483e-1");
216   check("1.0", 3, MPFR_RNDZ, "3.3333333333333331483e-1");
217   check("1.0", 3, MPFR_RNDU, "3.3333333333333337034e-1");
218   check("1.0", 3, MPFR_RNDD, "3.3333333333333331483e-1");
219   check("1.0", 2116118, MPFR_RNDN, "4.7256343927890600483e-7");
220   check("1.098612288668109782", 5, MPFR_RNDN, "0.21972245773362195087");
221 
222   mpfr_init2 (x, 53);
223   mpfr_set_ui (x, 3, MPFR_RNDD);
224   mpfr_log (x, x, MPFR_RNDD);
225   mpfr_div_ui (x, x, 5, MPFR_RNDD);
226   if (mpfr_cmp_str1 (x, "0.21972245773362189536"))
227     {
228       printf ("Error in mpfr_div_ui for x=ln(3), u=5\n");
229       exit (1);
230     }
231   mpfr_clear (x);
232 
233   test_generic_ui (2, 200, 100);
234 
235   tests_end_mpfr ();
236   return 0;
237 }
238