|
Packit |
5c3484 |
/*
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
Copyright 2012, 2013 Free Software Foundation, Inc.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
This file is part of the GNU MP Library test suite.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
The GNU MP Library test suite is free software; you can redistribute it
|
|
Packit |
5c3484 |
and/or modify it under the terms of the GNU General Public License as
|
|
Packit |
5c3484 |
published by the Free Software Foundation; either version 3 of the License,
|
|
Packit |
5c3484 |
or (at your option) any later version.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
The GNU MP Library test suite is distributed in the hope that it will be
|
|
Packit |
5c3484 |
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
5c3484 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
|
Packit |
5c3484 |
Public License for more details.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
You should have received a copy of the GNU General Public License along with
|
|
Packit |
5c3484 |
the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
#include <assert.h>
|
|
Packit |
5c3484 |
#include <stdlib.h>
|
|
Packit |
5c3484 |
#include <stdio.h>
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
#include "testutils.h"
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
#define MAXBITS 400
|
|
Packit |
5c3484 |
#define COUNT 10000
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
typedef void div_qr_func (mpz_t, mpz_t, const mpz_t, const mpz_t);
|
|
Packit |
5c3484 |
typedef unsigned long div_qr_ui_func (mpz_t, mpz_t, const mpz_t, unsigned long);
|
|
Packit |
5c3484 |
typedef void div_func (mpz_t, const mpz_t, const mpz_t);
|
|
Packit |
5c3484 |
typedef unsigned long div_x_ui_func (mpz_t, const mpz_t, unsigned long);
|
|
Packit |
5c3484 |
typedef unsigned long div_ui_func (const mpz_t, unsigned long);
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
void
|
|
Packit |
5c3484 |
testmain (int argc, char **argv)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
unsigned i;
|
|
Packit |
5c3484 |
mpz_t a, b, q, r, rq, rr;
|
|
Packit |
5c3484 |
int div_p;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
mpz_init (a);
|
|
Packit |
5c3484 |
mpz_init (b);
|
|
Packit |
5c3484 |
mpz_init (r);
|
|
Packit |
5c3484 |
mpz_init (q);
|
|
Packit |
5c3484 |
mpz_init (rr);
|
|
Packit |
5c3484 |
mpz_init (rq);
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
for (i = 0; i < COUNT; i++)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
unsigned j;
|
|
Packit |
5c3484 |
for (j = 0; j < 3; j++)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
static const enum hex_random_op ops[3] = { OP_CDIV, OP_FDIV, OP_TDIV };
|
|
Packit |
5c3484 |
static const char name[3] = { 'c', 'f', 't'};
|
|
Packit |
5c3484 |
static div_qr_func * const div_qr [3] =
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
mpz_cdiv_qr, mpz_fdiv_qr, mpz_tdiv_qr
|
|
Packit |
5c3484 |
};
|
|
Packit |
5c3484 |
static div_qr_ui_func *div_qr_ui[3] =
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
mpz_cdiv_qr_ui, mpz_fdiv_qr_ui, mpz_tdiv_qr_ui
|
|
Packit |
5c3484 |
};
|
|
Packit |
5c3484 |
static div_func * const div_q [3] =
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
mpz_cdiv_q, mpz_fdiv_q, mpz_tdiv_q
|
|
Packit |
5c3484 |
};
|
|
Packit |
5c3484 |
static div_x_ui_func *div_q_ui[3] =
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
mpz_cdiv_q_ui, mpz_fdiv_q_ui, mpz_tdiv_q_ui
|
|
Packit |
5c3484 |
};
|
|
Packit |
5c3484 |
static div_func * const div_r [3] =
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
mpz_cdiv_r, mpz_fdiv_r, mpz_tdiv_r
|
|
Packit |
5c3484 |
};
|
|
Packit |
5c3484 |
static div_x_ui_func *div_r_ui[3] =
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
mpz_cdiv_r_ui, mpz_fdiv_r_ui, mpz_tdiv_r_ui
|
|
Packit |
5c3484 |
};
|
|
Packit |
5c3484 |
static div_ui_func *div_ui[3] =
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
mpz_cdiv_ui, mpz_fdiv_ui, mpz_tdiv_ui
|
|
Packit |
5c3484 |
};
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
mini_random_op4 (ops[j], MAXBITS, a, b, rq, rr);
|
|
Packit |
5c3484 |
div_qr[j] (q, r, a, b);
|
|
Packit |
5c3484 |
if (mpz_cmp (r, rr) || mpz_cmp (q, rq))
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
fprintf (stderr, "mpz_%cdiv_qr failed:\n", name[j]);
|
|
Packit |
5c3484 |
dump ("a", a);
|
|
Packit |
5c3484 |
dump ("b", b);
|
|
Packit |
5c3484 |
dump ("r ", r);
|
|
Packit |
5c3484 |
dump ("rref", rr);
|
|
Packit |
5c3484 |
dump ("q ", q);
|
|
Packit |
5c3484 |
dump ("qref", rq);
|
|
Packit |
5c3484 |
abort ();
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
mpz_set_si (q, -5);
|
|
Packit |
5c3484 |
div_q[j] (q, a, b);
|
|
Packit |
5c3484 |
if (mpz_cmp (q, rq))
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
fprintf (stderr, "mpz_%cdiv_q failed:\n", name[j]);
|
|
Packit |
5c3484 |
dump ("a", a);
|
|
Packit |
5c3484 |
dump ("b", b);
|
|
Packit |
5c3484 |
dump ("q ", q);
|
|
Packit |
5c3484 |
dump ("qref", rq);
|
|
Packit |
5c3484 |
abort ();
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
mpz_set_ui (r, ~5);
|
|
Packit |
5c3484 |
div_r[j] (r, a, b);
|
|
Packit |
5c3484 |
if (mpz_cmp (r, rr))
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
fprintf (stderr, "mpz_%cdiv_r failed:\n", name[j]);
|
|
Packit |
5c3484 |
dump ("a", a);
|
|
Packit |
5c3484 |
dump ("b", b);
|
|
Packit |
5c3484 |
dump ("r ", r);
|
|
Packit |
5c3484 |
dump ("rref", rr);
|
|
Packit |
5c3484 |
abort ();
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
if (j == 0) /* do this once, not for all roundings */
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
div_p = mpz_divisible_p (a, b);
|
|
Packit |
5c3484 |
if ((mpz_sgn (r) == 0) ^ (div_p != 0))
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
fprintf (stderr, "mpz_divisible_p failed:\n");
|
|
Packit |
5c3484 |
dump ("a", a);
|
|
Packit |
5c3484 |
dump ("b", b);
|
|
Packit |
5c3484 |
dump ("r ", r);
|
|
Packit |
5c3484 |
abort ();
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
if (j == 0 && mpz_sgn (b) < 0) /* ceil, negative divisor */
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
mpz_mod (r, a, b);
|
|
Packit |
5c3484 |
if (mpz_cmp (r, rr))
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
fprintf (stderr, "mpz_mod failed:\n");
|
|
Packit |
5c3484 |
dump ("a", a);
|
|
Packit |
5c3484 |
dump ("b", b);
|
|
Packit |
5c3484 |
dump ("r ", r);
|
|
Packit |
5c3484 |
dump ("rref", rr);
|
|
Packit |
5c3484 |
abort ();
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
if (j == 1 && mpz_sgn (b) > 0) /* floor, positive divisor */
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
mpz_mod (r, a, b);
|
|
Packit |
5c3484 |
if (mpz_cmp (r, rr))
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
fprintf (stderr, "mpz_mod failed:\n");
|
|
Packit |
5c3484 |
dump ("a", a);
|
|
Packit |
5c3484 |
dump ("b", b);
|
|
Packit |
5c3484 |
dump ("r ", r);
|
|
Packit |
5c3484 |
dump ("rref", rr);
|
|
Packit |
5c3484 |
abort ();
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
if (mpz_fits_ulong_p (b))
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
mp_limb_t rl;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
rl = div_qr_ui[j] (q, r, a, mpz_get_ui (b));
|
|
Packit |
5c3484 |
if (rl != mpz_get_ui (rr)
|
|
Packit |
5c3484 |
|| mpz_cmp (r, rr) || mpz_cmp (q, rq))
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
fprintf (stderr, "mpz_%cdiv_qr_ui failed:\n", name[j]);
|
|
Packit |
5c3484 |
dump ("a", a);
|
|
Packit |
5c3484 |
dump ("b", b);
|
|
Packit |
5c3484 |
fprintf(stderr, "rl = %lx\n", rl);
|
|
Packit |
5c3484 |
dump ("r ", r);
|
|
Packit |
5c3484 |
dump ("rref", rr);
|
|
Packit |
5c3484 |
dump ("q ", q);
|
|
Packit |
5c3484 |
dump ("qref", rq);
|
|
Packit |
5c3484 |
abort ();
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
mpz_set_si (q, 3);
|
|
Packit |
5c3484 |
rl = div_q_ui[j] (q, a, mpz_get_ui (b));
|
|
Packit |
5c3484 |
if (rl != mpz_get_ui (rr) || mpz_cmp (q, rq))
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
fprintf (stderr, "mpz_%cdiv_q_ui failed:\n", name[j]);
|
|
Packit |
5c3484 |
dump ("a", a);
|
|
Packit |
5c3484 |
dump ("b", b);
|
|
Packit |
5c3484 |
fprintf(stderr, "rl = %lx\n", rl);
|
|
Packit |
5c3484 |
dump ("rref", rr);
|
|
Packit |
5c3484 |
dump ("q ", q);
|
|
Packit |
5c3484 |
dump ("qref", rq);
|
|
Packit |
5c3484 |
abort ();
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
mpz_set_ui (r, 7);
|
|
Packit |
5c3484 |
rl = div_r_ui[j] (r, a, mpz_get_ui (b));
|
|
Packit |
5c3484 |
if (rl != mpz_get_ui (rr) || mpz_cmp (r, rr))
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
fprintf (stderr, "mpz_%cdiv_qr_ui failed:\n", name[j]);
|
|
Packit |
5c3484 |
dump ("a", a);
|
|
Packit |
5c3484 |
dump ("b", b);
|
|
Packit |
5c3484 |
fprintf(stderr, "rl = %lx\n", rl);
|
|
Packit |
5c3484 |
dump ("r ", r);
|
|
Packit |
5c3484 |
dump ("rref", rr);
|
|
Packit |
5c3484 |
abort ();
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
rl = div_ui[j] (a, mpz_get_ui (b));
|
|
Packit |
5c3484 |
if (rl != mpz_get_ui (rr))
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
fprintf (stderr, "mpz_%cdiv_qr_ui failed:\n", name[j]);
|
|
Packit |
5c3484 |
dump ("a", a);
|
|
Packit |
5c3484 |
dump ("b", b);
|
|
Packit |
5c3484 |
fprintf(stderr, "rl = %lx\n", rl);
|
|
Packit |
5c3484 |
dump ("rref", rr);
|
|
Packit |
5c3484 |
abort ();
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
if (j == 0) /* do this once, not for all roundings */
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
div_p = mpz_divisible_ui_p (a, mpz_get_ui (b));
|
|
Packit |
5c3484 |
if ((mpz_sgn (r) == 0) ^ (div_p != 0))
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
fprintf (stderr, "mpz_divisible_ui_p failed:\n");
|
|
Packit |
5c3484 |
dump ("a", a);
|
|
Packit |
5c3484 |
dump ("b", b);
|
|
Packit |
5c3484 |
dump ("r ", r);
|
|
Packit |
5c3484 |
abort ();
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
if (j == 1) /* floor */
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
mpz_mod_ui (r, a, mpz_get_ui (b));
|
|
Packit |
5c3484 |
if (mpz_cmp (r, rr))
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
fprintf (stderr, "mpz_mod failed:\n");
|
|
Packit |
5c3484 |
dump ("a", a);
|
|
Packit |
5c3484 |
dump ("b", b);
|
|
Packit |
5c3484 |
dump ("r ", r);
|
|
Packit |
5c3484 |
dump ("rref", rr);
|
|
Packit |
5c3484 |
abort ();
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
mpz_clear (a);
|
|
Packit |
5c3484 |
mpz_clear (b);
|
|
Packit |
5c3484 |
mpz_clear (r);
|
|
Packit |
5c3484 |
mpz_clear (q);
|
|
Packit |
5c3484 |
mpz_clear (rr);
|
|
Packit |
5c3484 |
mpz_clear (rq);
|
|
Packit |
5c3484 |
}
|