1
/* Test mpz_abs, mpz_add, mpz_cmp, mpz_cmp_ui, mpz_cdiv_qr_ui, mpz_cdiv_q_ui,
2
mpz_cdiv_r_ui, , mpz_cdiv_ui, mpz_mul_ui.
4
Copyright 1993, 1994, 1996, 2000, 2001, 2002 Free Software Foundation, Inc.
6
This file is part of the GNU MP Library.
8
The GNU MP 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 2.1 of the License, or (at your
11
option) any later version.
13
The GNU MP 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.
18
You should have received a copy of the GNU Lesser General Public License
19
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
20
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21
MA 02111-1307, USA. */
30
void dump_abort _PROTO ((char *, mpz_t, unsigned long));
31
void debug_mp _PROTO ((mpz_t, int));
34
main (int argc, char **argv)
37
mpz_t quotient, remainder;
38
mpz_t quotient2, remainder2;
40
mp_size_t dividend_size;
41
unsigned long divisor;
44
gmp_randstate_ptr rands;
46
unsigned long bsi, size_range;
47
unsigned long r_rq, r_q, r_r, r;
55
reps = atoi (argv[1]);
61
mpz_init (remainder2);
64
for (i = 0; i < reps; i++)
66
mpz_urandomb (bs, rands, 32);
67
size_range = mpz_get_ui (bs) % 10 + 2; /* 0..2047 bit operands */
71
mpz_rrandomb (bs, rands, 64);
72
divisor = mpz_get_ui (bs);
76
mpz_urandomb (bs, rands, size_range);
77
dividend_size = mpz_get_ui (bs);
78
mpz_rrandomb (dividend, rands, dividend_size);
80
mpz_urandomb (bs, rands, 2);
81
bsi = mpz_get_ui (bs);
83
mpz_neg (dividend, dividend);
85
/* printf ("%ld\n", SIZ (dividend)); */
87
r_rq = mpz_cdiv_qr_ui (quotient, remainder, dividend, divisor);
88
r_q = mpz_cdiv_q_ui (quotient2, dividend, divisor);
89
r_r = mpz_cdiv_r_ui (remainder2, dividend, divisor);
90
r = mpz_cdiv_ui (dividend, divisor);
92
/* First determine that the quotients and remainders computed
93
with different functions are equal. */
94
if (mpz_cmp (quotient, quotient2) != 0)
95
dump_abort ("quotients from mpz_cdiv_qr_ui and mpz_cdiv_q_ui differ",
97
if (mpz_cmp (remainder, remainder2) != 0)
98
dump_abort ("remainders from mpz_cdiv_qr_ui and mpz_cdiv_r_ui differ",
101
/* Check if the sign of the quotient is correct. */
102
if (mpz_cmp_ui (quotient, 0) != 0)
103
if ((mpz_cmp_ui (quotient, 0) < 0)
104
!= (mpz_cmp_ui (dividend, 0) < 0))
105
dump_abort ("quotient sign wrong", dividend, divisor);
107
/* Check if the remainder has the opposite sign as the (positive) divisor
108
(quotient rounded towards minus infinity). */
109
if (mpz_cmp_ui (remainder, 0) != 0)
110
if (mpz_cmp_ui (remainder, 0) > 0)
111
dump_abort ("remainder sign wrong", dividend, divisor);
113
mpz_mul_ui (temp, quotient, divisor);
114
mpz_add (temp, temp, remainder);
115
if (mpz_cmp (temp, dividend) != 0)
116
dump_abort ("n mod d != n - [n/d]*d", dividend, divisor);
118
mpz_abs (remainder, remainder);
119
if (mpz_cmp_ui (remainder, divisor) >= 0)
120
dump_abort ("remainder greater than divisor", dividend, divisor);
122
if (mpz_cmp_ui (remainder, r_rq) != 0)
123
dump_abort ("remainder returned from mpz_cdiv_qr_ui is wrong",
125
if (mpz_cmp_ui (remainder, r_q) != 0)
126
dump_abort ("remainder returned from mpz_cdiv_q_ui is wrong",
128
if (mpz_cmp_ui (remainder, r_r) != 0)
129
dump_abort ("remainder returned from mpz_cdiv_r_ui is wrong",
131
if (mpz_cmp_ui (remainder, r) != 0)
132
dump_abort ("remainder returned from mpz_cdiv_ui is wrong",
137
mpz_clear (dividend);
138
mpz_clear (quotient);
139
mpz_clear (remainder);
140
mpz_clear (quotient2);
141
mpz_clear (remainder2);
149
dump_abort (char *str, mpz_t dividend, unsigned long divisor)
151
fprintf (stderr, "ERROR: %s\n", str);
152
fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
153
fprintf (stderr, "divisor = %lX\n", divisor);
158
debug_mp (mpz_t x, int base)
160
mpz_out_str (stderr, base, x); fputc ('\n', stderr);