Blame tests/devel/divmod_1.c

Packit 5c3484
/*
Packit 5c3484
Copyright 1996, 1998, 2000, 2001, 2007 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
#include "tests.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
static void mpn_print (mp_ptr, mp_size_t);
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 1000
Packit 5c3484
#endif
Packit 5c3484
#ifndef TIMES
Packit 5c3484
#define TIMES OPS/SIZE
Packit 5c3484
#endif
Packit 5c3484
Packit 5c3484
#ifndef FSIZE
Packit 5c3484
#define FSIZE SIZE
Packit 5c3484
#endif
Packit 5c3484
Packit 5c3484
int
Packit 5c3484
main ()
Packit 5c3484
{
Packit 5c3484
  mp_limb_t np[SIZE];
Packit 5c3484
  mp_limb_t dx[SIZE + FSIZE + 2];
Packit 5c3484
  mp_limb_t dy[SIZE + FSIZE + 2];
Packit 5c3484
  mp_limb_t dlimb;
Packit 5c3484
  mp_size_t nn, fn;
Packit 5c3484
  mp_limb_t retx, rety;
Packit 5c3484
  int test;
Packit 5c3484
#if TIMES != 1
Packit 5c3484
  int i;
Packit 5c3484
  long t0, t;
Packit 5c3484
  double cyc;
Packit 5c3484
#endif
Packit 5c3484
Packit 5c3484
  for (test = 0; ; test++)
Packit 5c3484
    {
Packit 5c3484
#if TIMES == 1 && ! defined (PRINT)
Packit 5c3484
      if (test % (SIZE > 100000 ? 1 : 100000 / SIZE) == 0)
Packit 5c3484
	{
Packit 5c3484
	  printf ("\r%u", test);
Packit 5c3484
	  fflush (stdout);
Packit 5c3484
	}
Packit 5c3484
#endif
Packit 5c3484
Packit 5c3484
#ifdef RANDOM
Packit 5c3484
      nn = random () % (SIZE + 1);
Packit 5c3484
      fn = random () % (FSIZE + 1);
Packit 5c3484
#else
Packit 5c3484
      nn = SIZE;
Packit 5c3484
      fn = FSIZE;
Packit 5c3484
#endif
Packit 5c3484
Packit 5c3484
      dx[0] = 0x87654321;
Packit 5c3484
      dx[nn + fn + 1] = 0x12345678;
Packit 5c3484
      dy[0] = 0x87654321;
Packit 5c3484
      dy[nn + fn + 1] = 0x12345678;
Packit 5c3484
      mpn_random2 (np, nn);
Packit 5c3484
Packit 5c3484
#ifdef FIXED_DLIMB
Packit 5c3484
      dlimb = FIXED_DLIMB;
Packit 5c3484
#else
Packit 5c3484
      do
Packit 5c3484
	{
Packit 5c3484
	  mpn_random2 (&dlimb, 1);
Packit 5c3484
#ifdef FORCE_NORM
Packit 5c3484
	  dlimb |= GMP_NUMB_HIGHBIT;
Packit 5c3484
#endif
Packit 5c3484
#ifdef FORCE_UNNORM
Packit 5c3484
	  dlimb &= GMP_NUMB_MAX >> 1;
Packit 5c3484
#endif
Packit 5c3484
	}
Packit 5c3484
      while (dlimb == 0);
Packit 5c3484
#endif
Packit 5c3484
Packit 5c3484
#if defined (PRINT) || defined (XPRINT)
Packit 5c3484
      printf ("N=");
Packit 5c3484
      mpn_print (np, nn);
Packit 5c3484
      printf ("D=");
Packit 5c3484
      mpn_print (&dlimb, 1);
Packit 5c3484
      printf ("nn=%ld\n", (long) nn);
Packit 5c3484
#endif
Packit 5c3484
Packit 5c3484
#if TIMES != 1
Packit 5c3484
      t0 = cputime();
Packit 5c3484
      for (i = 0; i < TIMES; i++)
Packit 5c3484
	mpn_divrem_1 (dx + 1, 0L, np, nn, dlimb);
Packit 5c3484
      t = cputime() - t0;
Packit 5c3484
      cyc = ((double) t * CLOCK) / (TIMES * nn * 1000.0);
Packit 5c3484
      printf ("mpn_divrem_1 int:    %5ldms (%.3f cycles/limb) [%.2f Gb/s]\n",
Packit 5c3484
	      t, cyc,
Packit 5c3484
	      CLOCK/cyc*GMP_LIMB_BITS*GMP_LIMB_BITS/1e9);
Packit 5c3484
      t0 = cputime();
Packit 5c3484
      for (i = 0; i < TIMES; i++)
Packit 5c3484
	mpn_divrem_1 (dx + 1, fn, np, 0, dlimb);
Packit 5c3484
      t = cputime() - t0;
Packit 5c3484
      cyc = ((double) t * CLOCK) / (TIMES * fn * 1000.0);
Packit 5c3484
      printf ("mpn_divrem_1 frac:   %5ldms (%.3f cycles/limb) [%.2f Gb/s]\n",
Packit 5c3484
	      t, cyc,
Packit 5c3484
	      CLOCK/cyc*GMP_LIMB_BITS*GMP_LIMB_BITS/1e9);
Packit 5c3484
#endif
Packit 5c3484
Packit 5c3484
      retx = refmpn_divrem_1 (dx + 1, fn, np, nn, dlimb);
Packit 5c3484
      rety = mpn_divrem_1 (dy + 1, fn, np, nn, dlimb);
Packit 5c3484
Packit 5c3484
#ifndef NOCHECK
Packit 5c3484
      if (retx != rety || mpn_cmp (dx, dy, fn + nn + 2) != 0)
Packit 5c3484
	{
Packit 5c3484
	  printf ("ERROR in test %d, nn=%ld, fn=%ld\n", test, nn, fn);
Packit 5c3484
	  mpn_print (np, nn);
Packit 5c3484
	  mpn_print (&dlimb, 1);
Packit 5c3484
	  printf ("rq: ");
Packit 5c3484
	  mpn_print (dx + 1, nn + fn);
Packit 5c3484
	  printf ("rr: %*lX\n", (int) (2 * sizeof(mp_limb_t)), retx);
Packit 5c3484
	  printf (" q: ");
Packit 5c3484
	  mpn_print (dy + 1, nn + fn);
Packit 5c3484
	  printf (" r: %*lX\n", (int) (2 * sizeof(mp_limb_t)), rety);
Packit 5c3484
	  if (dy[0] != 0x87654321)
Packit 5c3484
	    printf ("clobbered at low end %*lX\n", (int) (2 * sizeof(mp_limb_t)), dy[0]);
Packit 5c3484
	  if (dy[nn + fn + 1] != 0x12345678)
Packit 5c3484
	    printf ("clobbered at high end\n");
Packit 5c3484
	  abort ();
Packit 5c3484
	}
Packit 5c3484
#endif
Packit 5c3484
    }
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
static void
Packit 5c3484
mpn_print (mp_ptr p, mp_size_t size)
Packit 5c3484
{
Packit 5c3484
  mp_size_t i;
Packit 5c3484
Packit 5c3484
  for (i = size - 1; i >= 0; i--)
Packit 5c3484
    {
Packit 5c3484
#ifdef _LONG_LONG_LIMB
Packit 5c3484
      printf ("%0*lX%0*lX", (int) (sizeof(mp_limb_t)),
Packit 5c3484
	      (unsigned long) (p[i] >> (GMP_LIMB_BITS/2)),
Packit 5c3484
              (int) (sizeof(mp_limb_t)), (unsigned long) (p[i]));
Packit 5c3484
#else
Packit 5c3484
      printf ("%0*lX", (int) (2 * sizeof(mp_limb_t)), p[i]);
Packit 5c3484
#endif
Packit 5c3484
#ifdef SPACE
Packit 5c3484
      if (i != 0)
Packit 5c3484
	printf (" ");
Packit 5c3484
#endif
Packit 5c3484
    }
Packit 5c3484
  puts ("");
Packit 5c3484
}