blob: 9db8a6164cf0d78c300fce358f3f26bd93c601ce [file] [log] [blame]
Austin Schuhbb1338c2024-06-15 19:31:16 -07001/* Test mpz_add, mpz_add_ui, mpz_cmp, mpz_cmp, mpz_mul, mpz_sqrtrem.
2
3Copyright 1991, 1993, 1994, 1996, 2000-2002 Free Software Foundation, Inc.
4
5This file is part of the GNU MP Library test suite.
6
7The GNU MP Library test suite is free software; you can redistribute it
8and/or modify it under the terms of the GNU General Public License as
9published by the Free Software Foundation; either version 3 of the License,
10or (at your option) any later version.
11
12The GNU MP Library test suite is distributed in the hope that it will be
13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15Public License for more details.
16
17You should have received a copy of the GNU General Public License along with
18the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */
19
20#include <stdio.h>
21#include <stdlib.h>
22
23#include "gmp-impl.h"
24#include "tests.h"
25
26void dump_abort (mpz_t, mpz_t, mpz_t);
27void debug_mp (mpz_t, int);
28
29int
30main (int argc, char **argv)
31{
32 mpz_t x2;
33 mpz_t x, rem;
34 mpz_t temp, temp2;
35 mp_size_t x2_size;
36 int i;
37 int reps = 1000;
38 gmp_randstate_ptr rands;
39 mpz_t bs;
40 unsigned long size_range;
41
42 tests_start ();
43 TESTS_REPS (reps, argv, argc);
44
45 rands = RANDS;
46
47 mpz_init (bs);
48
49 mpz_init (x2);
50 mpz_init (x);
51 mpz_init (rem);
52 mpz_init (temp);
53 mpz_init (temp2);
54
55 for (i = 0; i < reps; i++)
56 {
57 mpz_urandomb (bs, rands, 32);
58 size_range = mpz_get_ui (bs) % 17 + 2; /* 0..262144 bit operands */
59
60 mpz_urandomb (bs, rands, size_range);
61 x2_size = mpz_get_ui (bs);
62 mpz_rrandomb (x2, rands, x2_size);
63
64 /* printf ("%ld\n", SIZ (x2)); */
65
66 mpz_sqrt (temp, x2);
67 MPZ_CHECK_FORMAT (temp);
68
69 mpz_sqrtrem (x, rem, x2);
70 MPZ_CHECK_FORMAT (x);
71 MPZ_CHECK_FORMAT (rem);
72
73 /* Are results different? */
74 if (mpz_cmp (temp, x) != 0)
75 dump_abort (x2, x, rem);
76
77 mpz_mul (temp, x, x);
78
79 /* Is square of result > argument? */
80 if (mpz_cmp (temp, x2) > 0)
81 dump_abort (x2, x, rem);
82
83 mpz_add_ui (temp2, x, 1);
84 mpz_mul (temp2, temp2, temp2);
85
86 /* Is square of (result + 1) <= argument? */
87 if (mpz_cmp (temp2, x2) <= 0)
88 dump_abort (x2, x, rem);
89
90 mpz_add (temp2, temp, rem);
91
92 /* Is the remainder wrong? */
93 if (mpz_cmp (x2, temp2) != 0)
94 dump_abort (x2, x, rem);
95 }
96
97 mpz_clear (bs);
98 mpz_clear (x2);
99 mpz_clear (x);
100 mpz_clear (rem);
101 mpz_clear (temp);
102 mpz_clear (temp2);
103
104 tests_end ();
105 exit (0);
106}
107
108void
109dump_abort (mpz_t x2, mpz_t x, mpz_t rem)
110{
111 fprintf (stderr, "ERROR\n");
112 fprintf (stderr, "x2 = "); debug_mp (x2, -16);
113 fprintf (stderr, "x = "); debug_mp (x, -16);
114 fprintf (stderr, "remainder = "); debug_mp (rem, -16);
115 abort();
116}
117
118void
119debug_mp (mpz_t x, int base)
120{
121 mpz_out_str (stderr, base, x); fputc ('\n', stderr);
122}