Blame tests/devel/divrem.c

Packit 5c3484
/*
Packit 5c3484
Copyright 1996-1998, 2000, 2001, 2007, 2009 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 <stdio.h>
Packit 5c3484
#include <stdlib.h>
Packit 5c3484
#include "gmp.h"
Packit 5c3484
#include "gmp-impl.h"
Packit 5c3484
Packit 5c3484
#if defined (USG) || defined (__SVR4) || defined (_UNICOS) || defined (__hpux)
Packit 5c3484
#include <time.h>
Packit 5c3484
Packit 5c3484
int
Packit 5c3484
cputime ()
Packit 5c3484
{
Packit 5c3484
  if (CLOCKS_PER_SEC < 100000)
Packit 5c3484
    return clock () * 1000 / CLOCKS_PER_SEC;
Packit 5c3484
  return clock () / (CLOCKS_PER_SEC / 1000);
Packit 5c3484
}
Packit 5c3484
#else
Packit 5c3484
#include <sys/types.h>
Packit 5c3484
#include <sys/time.h>
Packit 5c3484
#include <sys/resource.h>
Packit 5c3484
Packit 5c3484
int
Packit 5c3484
cputime ()
Packit 5c3484
{
Packit 5c3484
  struct rusage rus;
Packit 5c3484
Packit 5c3484
  getrusage (0, &rus;;
Packit 5c3484
  return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
Packit 5c3484
}
Packit 5c3484
#endif
Packit 5c3484
Packit 5c3484
#define M * 1000000
Packit 5c3484
Packit 5c3484
#ifndef CLOCK
Packit 5c3484
#error "Don't know CLOCK of your machine"
Packit 5c3484
#endif
Packit 5c3484
Packit 5c3484
#ifndef OPS
Packit 5c3484
#define OPS 20000000
Packit 5c3484
#endif
Packit 5c3484
#ifndef SIZE
Packit 5c3484
#define SIZE 100
Packit 5c3484
#endif
Packit 5c3484
#ifndef TIMES
Packit 5c3484
#define TIMES OPS/(SIZE+1)
Packit 5c3484
#endif
Packit 5c3484
Packit 5c3484
int
Packit 5c3484
main ()
Packit 5c3484
{
Packit 5c3484
  mp_limb_t nptr[2 * SIZE];
Packit 5c3484
  mp_limb_t dptr[2 * SIZE];
Packit 5c3484
  mp_limb_t qptr[2 * SIZE];
Packit 5c3484
  mp_limb_t pptr[2 * SIZE + 1];
Packit 5c3484
  mp_limb_t rptr[2 * SIZE];
Packit 5c3484
  mp_size_t nsize, dsize, qsize, rsize, psize;
Packit 5c3484
  int test;
Packit 5c3484
  mp_limb_t qlimb;
Packit 5c3484
Packit 5c3484
  for (test = 0; ; test++)
Packit 5c3484
    {
Packit 5c3484
      printf ("%d\n", test);
Packit 5c3484
#ifdef RANDOM
Packit 5c3484
      nsize = random () % (2 * SIZE) + 1;
Packit 5c3484
      dsize = random () % nsize + 1;
Packit 5c3484
#else
Packit 5c3484
      nsize = 2 * SIZE;
Packit 5c3484
      dsize = SIZE;
Packit 5c3484
#endif
Packit 5c3484
Packit 5c3484
      mpn_random2 (nptr, nsize);
Packit 5c3484
      mpn_random2 (dptr, dsize);
Packit 5c3484
      dptr[dsize - 1] |= (mp_limb_t) 1 << (GMP_LIMB_BITS - 1);
Packit 5c3484
Packit 5c3484
      MPN_COPY (rptr, nptr, nsize);
Packit 5c3484
      qlimb = mpn_divrem (qptr, (mp_size_t) 0, rptr, nsize, dptr, dsize);
Packit 5c3484
      rsize = dsize;
Packit 5c3484
      qsize = nsize - dsize;
Packit 5c3484
      qptr[qsize] = qlimb;
Packit 5c3484
      qsize += qlimb;
Packit 5c3484
      if (qsize == 0 || qsize > 2 * SIZE)
Packit 5c3484
	{
Packit 5c3484
	  continue;		/* bogus */
Packit 5c3484
	}
Packit 5c3484
      else
Packit 5c3484
	{
Packit 5c3484
	  mp_limb_t cy;
Packit 5c3484
	  if (qsize > dsize)
Packit 5c3484
	    mpn_mul (pptr, qptr, qsize, dptr, dsize);
Packit 5c3484
	  else
Packit 5c3484
	    mpn_mul (pptr, dptr, dsize, qptr, qsize);
Packit 5c3484
	  psize = qsize + dsize;
Packit 5c3484
	  psize -= pptr[psize - 1] == 0;
Packit 5c3484
	  cy = mpn_add (pptr, pptr, psize, rptr, rsize);
Packit 5c3484
	  pptr[psize] = cy;
Packit 5c3484
	  psize += cy;
Packit 5c3484
	}
Packit 5c3484
Packit 5c3484
      if (nsize != psize || mpn_cmp (nptr, pptr, nsize) != 0)
Packit 5c3484
	abort ();
Packit 5c3484
    }
Packit 5c3484
}