// Copyright, 2001-2003, Astra Network Inc.  All Rights Reserved

// This source code has been published by Astra Network Inc. However, any
// use, reproduction, modification, distribution or transfer of this
// software, or any software which includes or is based upon any of this
// code, is only permitted if expressly authorized by a written license
// agreement from Astra. Contact your Astra representative directly for
// more information.

#include <stdio.h>
#include <quad.h>
#include <time.h>

int
main (int argc, char *argv[])
{
  union
  {
    ___quad_t q;
    long long ll;
    unsigned long v[2];
  }
  a, b, q, r;
  extern ___quad_t quad_qdivrem (___u_quad_t, ___u_quad_t, ___u_quad_t *);
  int rounds, i, errors = 0;
  long long ll, rem;

  if (argc == 2)
    {
      rounds = (int) atoi (argv[1]);
    }
  else
    {
      printf ("Enter a number on the command line\n");
      exit (1);
    }
  printf ("Testing division.\n");
  printf ("0|                    |100\e[24D");

  srand48 (time (NULL));
  for (i = 0; i < rounds * 100; i++)
    {
      a.v[0] = lrand48 ();
      a.v[1] = lrand48 ();
      b.v[0] = lrand48 ();
      b.v[1] = lrand48 ();

      q.q = quad_qdivrem (a.q, b.q, &r.q);
      ll = a.ll / b.ll;
      rem = a.ll % b.ll;

      if ((q.ll == ll) && (r.ll == rem))
	{
	  if (i % (rounds * 100 / 20) == 0)
	    {
	      printf (".");
	      fflush (stdout);
	    }
	}
      else
	{
	  printf ("Wrong. %llX / %llX != %llX (gcc %llX)\n",
		  a.ll, b.ll, q.ll, ll);
	  printf ("       %llX % %llX != %llX (gcc %llX)\n",
		  a.ll, b.ll, r.ll, rem);
	  errors++;
	}

    }

  if (errors)
    {
      printf ("\n%d errors.\n", errors);
      exit (1);
    }
  else
    {
      printf ("\nNo errors\n");
      exit (0);
    }

}
