[BACK]Return to t-div_2exp.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / tests / mpz

Annotation of OpenXM_contrib/gmp/tests/mpz/t-div_2exp.c, Revision 1.1.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>