xref: /netbsd-src/external/lgpl3/gmp/dist/tests/mpf/t-ui_div.c (revision 6d322f2f4598f0d8a138f10ea648ec4fabe41f8b)
1 /* Test mpf_ui_div.
2 
3 Copyright 2004 Free Software Foundation, Inc.
4 
5 This file is part of the GNU MP Library test suite.
6 
7 The GNU MP Library test suite is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 3 of the License,
10 or (at your option) any later version.
11 
12 The GNU MP Library test suite is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
15 Public License for more details.
16 
17 You should have received a copy of the GNU General Public License along with
18 the GNU MP Library test suite.  If not, see http://www.gnu.org/licenses/.  */
19 
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include "gmp.h"
23 #include "gmp-impl.h"
24 #include "tests.h"
25 
26 
27 void
28 check_one (const char *desc, mpf_ptr got, unsigned long u, mpf_srcptr v)
29 {
30   mpf_t      uf;
31   mp_limb_t  ulimbs[2];
32   mp_size_t  usize;
33 
34   ulimbs[0] = u & GMP_NUMB_MASK;
35   usize = (u != 0);
36 #if BITS_PER_ULONG > GMP_NUMB_BITS
37   u >>= GMP_NUMB_BITS;
38   ulimbs[1] = u;
39   usize += (u != 0);
40 #endif
41   PTR(uf) = ulimbs;
42   SIZ(uf) = usize;
43   EXP(uf) = usize;
44 
45   if (! refmpf_validate_division ("mpf_ui_div", got, uf, v))
46     {
47       mp_trace_base = -16;
48       printf    ("  u 0x%lX  (%lu)\n", u, u);
49       mpf_trace ("  v", v);
50       printf    ("  %s\n", desc);
51       abort ();
52     }
53 }
54 
55 void
56 check_rand (void)
57 {
58   unsigned long  min_prec = __GMPF_BITS_TO_PREC (1);
59   gmp_randstate_ptr  rands = RANDS;
60   unsigned long  prec, u;
61   mpf_t  got, v;
62   int    i;
63 
64   mpf_init (got);
65   mpf_init (v);
66 
67   for (i = 0; i < 200; i++)
68     {
69       /* got precision */
70       prec = min_prec + gmp_urandomm_ui (rands, 15L);
71       refmpf_set_prec_limbs (got, prec);
72 
73       /* u */
74       prec = gmp_urandomm_ui (rands, BITS_PER_ULONG+1);
75       u = gmp_urandomb_ui (rands, prec);
76 
77       /* v precision */
78       prec = min_prec + gmp_urandomm_ui (rands, 15L);
79       refmpf_set_prec_limbs (v, prec);
80 
81       /* v, non-zero */
82       do {
83         mpf_random2 (v, PREC(v), (mp_exp_t) 20);
84       } while (SIZ(v) == 0);
85 
86       /* v possibly negative */
87       if (gmp_urandomb_ui (rands, 1L))
88         mpf_neg (v, v);
89 
90       if ((i % 2) == 0)
91         {
92           /* src != dst */
93           mpf_ui_div (got, u, v);
94           check_one ("separate", got, u, v);
95         }
96       else
97         {
98           /* src == dst */
99           prec = refmpf_set_overlap (got, v);
100           mpf_ui_div (got, u, got);
101           check_one ("overlap src==dst", got, u, v);
102 
103           mpf_set_prec_raw (got, prec);
104         }
105     }
106 
107   mpf_clear (got);
108   mpf_clear (v);
109 }
110 
111 void
112 check_various (void)
113 {
114   mpf_t got, v;
115 
116   mpf_init (got);
117   mpf_init (v);
118 
119   /* 100/4 == 25 */
120   mpf_set_prec (got, 20L);
121   mpf_set_ui (v, 4L);
122   mpf_ui_div (got, 100L, v);
123   MPF_CHECK_FORMAT (got);
124   ASSERT_ALWAYS (mpf_cmp_ui (got, 25L) == 0);
125 
126   {
127     /* 1/(2^n+1), a case where truncating the divisor would be wrong */
128     unsigned long  u = 1L;
129     mpf_set_prec (got, 500L);
130     mpf_set_prec (v, 900L);
131     mpf_set_ui (v, 1L);
132     mpf_mul_2exp (v, v, 800L);
133     mpf_add_ui (v, v, 1L);
134     mpf_ui_div (got, u, v);
135     check_one ("1/2^n+1, separate", got, u, v);
136   }
137 
138   mpf_clear (got);
139   mpf_clear (v);
140 }
141 
142 int
143 main (void)
144 {
145   tests_start ();
146 
147   check_various ();
148   check_rand ();
149 
150   tests_end ();
151   exit (0);
152 }
153