xref: /netbsd-src/external/lgpl3/gmp/dist/tests/mpf/t-ui_div.c (revision 72c7faa4dbb41dbb0238d6b4a109da0d4b236dd4)
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 https://www.gnu.org/licenses/.  */
19 
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include "gmp-impl.h"
23 #include "tests.h"
24 
25 
26 void
check_one(const char * desc,mpf_ptr got,unsigned long u,mpf_srcptr v)27 check_one (const char *desc, mpf_ptr got, unsigned long u, mpf_srcptr v)
28 {
29   mpf_t      uf;
30   mp_limb_t  ulimbs[2];
31   mp_size_t  usize;
32 
33   ulimbs[0] = u & GMP_NUMB_MASK;
34   usize = (u != 0);
35 #if BITS_PER_ULONG > GMP_NUMB_BITS
36   u >>= GMP_NUMB_BITS;
37   ulimbs[1] = u;
38   usize += (u != 0);
39 #endif
40   PTR(uf) = ulimbs;
41   SIZ(uf) = usize;
42   EXP(uf) = usize;
43 
44   if (! refmpf_validate_division ("mpf_ui_div", got, uf, v))
45     {
46       mp_trace_base = -16;
47       printf    ("  u 0x%lX  (%lu)\n", u, u);
48       mpf_trace ("  v", v);
49       printf    ("  %s\n", desc);
50       abort ();
51     }
52 }
53 
54 void
check_rand(void)55 check_rand (void)
56 {
57   unsigned long  min_prec = __GMPF_BITS_TO_PREC (1);
58   gmp_randstate_ptr  rands = RANDS;
59   unsigned long  prec, u;
60   mpf_t  got, v;
61   int    i;
62 
63   mpf_init (got);
64   mpf_init (v);
65 
66   for (i = 0; i < 200; i++)
67     {
68       /* got precision */
69       prec = min_prec + gmp_urandomm_ui (rands, 15L);
70       refmpf_set_prec_limbs (got, prec);
71 
72       /* u */
73       prec = gmp_urandomm_ui (rands, BITS_PER_ULONG+1);
74       u = gmp_urandomb_ui (rands, prec);
75 
76       /* v precision */
77       prec = min_prec + gmp_urandomm_ui (rands, 15L);
78       refmpf_set_prec_limbs (v, prec);
79 
80       /* v, non-zero */
81       do {
82         mpf_random2 (v, PREC(v), (mp_exp_t) 20);
83       } while (SIZ(v) == 0);
84 
85       /* v possibly negative */
86       if (gmp_urandomb_ui (rands, 1L))
87         mpf_neg (v, v);
88 
89       if ((i % 2) == 0)
90         {
91           /* src != dst */
92           mpf_ui_div (got, u, v);
93           check_one ("separate", got, u, v);
94         }
95       else
96         {
97           /* src == dst */
98           prec = refmpf_set_overlap (got, v);
99           mpf_ui_div (got, u, got);
100           check_one ("overlap src==dst", got, u, v);
101 
102           mpf_set_prec_raw (got, prec);
103         }
104     }
105 
106   mpf_clear (got);
107   mpf_clear (v);
108 }
109 
110 void
check_various(void)111 check_various (void)
112 {
113   mpf_t got, v;
114 
115   mpf_init (got);
116   mpf_init (v);
117 
118   /* 100/4 == 25 */
119   mpf_set_prec (got, 20L);
120   mpf_set_ui (v, 4L);
121   mpf_ui_div (got, 100L, v);
122   MPF_CHECK_FORMAT (got);
123   ASSERT_ALWAYS (mpf_cmp_ui (got, 25L) == 0);
124 
125   {
126     /* 1/(2^n+1), a case where truncating the divisor would be wrong */
127     unsigned long  u = 1L;
128     mpf_set_prec (got, 500L);
129     mpf_set_prec (v, 900L);
130     mpf_set_ui (v, 1L);
131     mpf_mul_2exp (v, v, 800L);
132     mpf_add_ui (v, v, 1L);
133     mpf_ui_div (got, u, v);
134     check_one ("1/2^n+1, separate", got, u, v);
135   }
136 
137   mpf_clear (got);
138   mpf_clear (v);
139 }
140 
141 int
main(void)142 main (void)
143 {
144   tests_start ();
145 
146   check_various ();
147   check_rand ();
148 
149   tests_end ();
150   exit (0);
151 }
152