Annotation of OpenXM_contrib/gmp/tests/mpz/t-div_2exp.c, Revision 1.1
1.1 ! ohara 1: /* Test mpz_[cft]div_[qr]_2exp.
! 2:
! 3: Copyright 2001 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 2.1 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; see the file COPYING.LIB. If not, write to
! 19: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
! 20: MA 02111-1307, USA. */
! 21:
! 22: #include <stdio.h>
! 23: #include <stdlib.h>
! 24:
! 25: #include "gmp.h"
! 26: #include "gmp-impl.h"
! 27: #include "tests.h"
! 28:
! 29:
! 30: /* If the remainder is in the correct range and q*d+r is correct, then q
! 31: must have rounded correctly. */
! 32:
! 33: void
! 34: check_one (mpz_srcptr a, unsigned long d)
! 35: {
! 36: mpz_t q, r, p, d2exp;
! 37: int inplace;
! 38:
! 39: mpz_init (d2exp);
! 40: mpz_init (q);
! 41: mpz_init (r);
! 42: mpz_init (p);
! 43:
! 44: mpz_set_ui (d2exp, 1L);
! 45: mpz_mul_2exp (d2exp, d2exp, d);
! 46:
! 47: #define INPLACE(fun,dst,src,d) \
! 48: if (inplace) \
! 49: { \
! 50: mpz_set (dst, src); \
! 51: fun (dst, dst, d); \
! 52: } \
! 53: else \
! 54: fun (dst, src, d);
! 55:
! 56: for (inplace = 0; inplace <= 1; inplace++)
! 57: {
! 58: INPLACE (mpz_fdiv_q_2exp, q, a, d);
! 59: INPLACE (mpz_fdiv_r_2exp, r, a, d);
! 60:
! 61: mpz_mul_2exp (p, q, d);
! 62: mpz_add (p, p, r);
! 63: if (mpz_sgn (r) < 0 || mpz_cmp (r, d2exp) >= 0)
! 64: {
! 65: printf ("mpz_fdiv_r_2exp result out of range\n");
! 66: goto error;
! 67: }
! 68: if (mpz_cmp (p, a) != 0)
! 69: {
! 70: printf ("mpz_fdiv_[qr]_2exp doesn't multiply back\n");
! 71: goto error;
! 72: }
! 73:
! 74:
! 75: INPLACE (mpz_cdiv_q_2exp, q, a, d);
! 76: INPLACE (mpz_cdiv_r_2exp, r, a, d);
! 77:
! 78: mpz_mul_2exp (p, q, d);
! 79: mpz_add (p, p, r);
! 80: if (mpz_sgn (r) > 0 || mpz_cmpabs (r, d2exp) >= 0)
! 81: {
! 82: printf ("mpz_cdiv_r_2exp result out of range\n");
! 83: goto error;
! 84: }
! 85: if (mpz_cmp (p, a) != 0)
! 86: {
! 87: printf ("mpz_cdiv_[qr]_2exp doesn't multiply back\n");
! 88: goto error;
! 89: }
! 90:
! 91:
! 92: INPLACE (mpz_tdiv_q_2exp, q, a, d);
! 93: INPLACE (mpz_tdiv_r_2exp, r, a, d);
! 94:
! 95: mpz_mul_2exp (p, q, d);
! 96: mpz_add (p, p, r);
! 97: if (mpz_sgn (r) != 0 && mpz_sgn (r) != mpz_sgn (a))
! 98: {
! 99: printf ("mpz_tdiv_r_2exp result wrong sign\n");
! 100: goto error;
! 101: }
! 102: if (mpz_cmpabs (r, d2exp) >= 0)
! 103: {
! 104: printf ("mpz_tdiv_r_2exp result out of range\n");
! 105: goto error;
! 106: }
! 107: if (mpz_cmp (p, a) != 0)
! 108: {
! 109: printf ("mpz_tdiv_[qr]_2exp doesn't multiply back\n");
! 110: goto error;
! 111: }
! 112: }
! 113:
! 114: mpz_clear (d2exp);
! 115: mpz_clear (q);
! 116: mpz_clear (r);
! 117: mpz_clear (p);
! 118: return;
! 119:
! 120:
! 121: error:
! 122: mpz_trace ("a", a);
! 123: printf ("d=%lu\n", d);
! 124: mpz_trace ("q", q);
! 125: mpz_trace ("r", r);
! 126: mpz_trace ("p", p);
! 127:
! 128: mp_trace_base = -16;
! 129: mpz_trace ("a", a);
! 130: printf ("d=0x%lX\n", d);
! 131: mpz_trace ("q", q);
! 132: mpz_trace ("r", r);
! 133: mpz_trace ("p", p);
! 134:
! 135: abort ();
! 136: }
! 137:
! 138:
! 139: void
! 140: check_all (mpz_ptr a, unsigned long d)
! 141: {
! 142: check_one (a, d);
! 143: mpz_neg (a, a);
! 144: check_one (a, d);
! 145: }
! 146:
! 147:
! 148: void
! 149: check_various (void)
! 150: {
! 151: unsigned long i, d;
! 152: mpz_t a;
! 153:
! 154: mpz_init (a);
! 155:
! 156: /* a==0, and various d */
! 157: mpz_set_ui (a, 0L);
! 158: for (d = 0; d < 2*BITS_PER_MP_LIMB+4; d++)
! 159: check_one (a, d);
! 160:
! 161: /* a==2^i, and various d */
! 162: for (i = 0; i < 5*BITS_PER_MP_LIMB; i++)
! 163: {
! 164: d = (i < BITS_PER_MP_LIMB+3 ? 0 : i-(BITS_PER_MP_LIMB+3));
! 165: for ( ; d < i+BITS_PER_MP_LIMB+3; d++)
! 166: {
! 167: mpz_set_ui (a, 1L);
! 168: mpz_mul_2exp (a, a, i);
! 169: check_all (a, d);
! 170: }
! 171: }
! 172:
! 173: mpz_clear (a);
! 174: }
! 175:
! 176:
! 177: void
! 178: check_random (int argc, char *argv[])
! 179: {
! 180: gmp_randstate_ptr rands = RANDS;
! 181: int reps = 5000;
! 182: mpz_t a;
! 183: unsigned long d;
! 184: int i;
! 185:
! 186: if (argc == 2)
! 187: reps = atoi (argv[1]);
! 188:
! 189: mpz_init (a);
! 190:
! 191: for (i = 0; i < reps; i++)
! 192: {
! 193: /* exponentially within 2 to 257 bits */
! 194: mpz_erandomb (a, rands, urandom () % 8 + 2);
! 195:
! 196: d = urandom () % 256;
! 197:
! 198: check_all (a, d);
! 199: }
! 200:
! 201: mpz_clear (a);
! 202: }
! 203:
! 204:
! 205: int
! 206: main (int argc, char *argv[])
! 207: {
! 208: tests_start ();
! 209:
! 210: check_various ();
! 211: check_random (argc, argv);
! 212:
! 213: tests_end ();
! 214: exit (0);
! 215: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>