Tizen 2.1 base
[external/gmp.git] / tests / mpf / t-ui_div.c
1 /* Test mpf_ui_div.
2
3 Copyright 2004 Free Software Foundation, Inc.
4
5 This file is part of the GNU MP Library.
6
7 The GNU MP Library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11
12 The GNU MP Library is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15 License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with the GNU MP Library.  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 }