github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/mini-gmp/tests/t-div.c (about)

     1  /*
     2  
     3  Copyright 2012, 2013 Free Software Foundation, Inc.
     4  
     5  This file is part of the GNU MP Library test suite.
     6  
     7  The GNU MP Library test suite is free software; you can redistribute it
     8  and/or modify it under the terms of the GNU General Public License as
     9  published by the Free Software Foundation; either version 3 of the License,
    10  or (at your option) any later version.
    11  
    12  The GNU MP Library test suite is distributed in the hope that it will be
    13  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
    15  Public License for more details.
    16  
    17  You should have received a copy of the GNU General Public License along with
    18  the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
    19  
    20  #include <assert.h>
    21  #include <stdlib.h>
    22  #include <stdio.h>
    23  
    24  #include "testutils.h"
    25  
    26  #define MAXBITS 400
    27  #define COUNT 10000
    28  
    29  typedef void div_qr_func (mpz_t, mpz_t, const mpz_t, const mpz_t);
    30  typedef unsigned long div_qr_ui_func (mpz_t, mpz_t, const mpz_t, unsigned long);
    31  typedef void div_func (mpz_t, const mpz_t, const mpz_t);
    32  typedef unsigned long div_x_ui_func (mpz_t, const mpz_t, unsigned long);
    33  typedef unsigned long div_ui_func (const mpz_t, unsigned long);
    34  
    35  void
    36  testmain (int argc, char **argv)
    37  {
    38    unsigned i;
    39    mpz_t a, b, q, r, rq, rr;
    40    int div_p;
    41  
    42    mpz_init (a);
    43    mpz_init (b);
    44    mpz_init (r);
    45    mpz_init (q);
    46    mpz_init (rr);
    47    mpz_init (rq);
    48  
    49    for (i = 0; i < COUNT; i++)
    50      {
    51        unsigned j;
    52        for (j = 0; j < 3; j++)
    53  	{
    54  	  static const enum hex_random_op ops[3] = { OP_CDIV, OP_FDIV, OP_TDIV };
    55  	  static const char name[3] = { 'c', 'f', 't'};
    56  	  static div_qr_func * const div_qr [3] =
    57  	    {
    58  	      mpz_cdiv_qr, mpz_fdiv_qr, mpz_tdiv_qr
    59  	    };
    60  	  static div_qr_ui_func  *div_qr_ui[3] =
    61  	    {
    62  	      mpz_cdiv_qr_ui, mpz_fdiv_qr_ui, mpz_tdiv_qr_ui
    63  	    };
    64  	  static div_func * const div_q [3] =
    65  	    {
    66  	      mpz_cdiv_q, mpz_fdiv_q, mpz_tdiv_q
    67  	    };
    68  	  static div_x_ui_func  *div_q_ui[3] =
    69  	    {
    70  	      mpz_cdiv_q_ui, mpz_fdiv_q_ui, mpz_tdiv_q_ui
    71  	    };
    72  	  static div_func * const div_r [3] =
    73  	    {
    74  	      mpz_cdiv_r, mpz_fdiv_r, mpz_tdiv_r
    75  	    };
    76  	  static div_x_ui_func  *div_r_ui[3] =
    77  	    {
    78  	      mpz_cdiv_r_ui, mpz_fdiv_r_ui, mpz_tdiv_r_ui
    79  	    };
    80  	  static div_ui_func  *div_ui[3] =
    81  	    {
    82  	      mpz_cdiv_ui, mpz_fdiv_ui, mpz_tdiv_ui
    83  	    };
    84  
    85  	  mini_random_op4 (ops[j], MAXBITS, a, b, rq, rr);
    86  	  div_qr[j] (q, r, a, b);
    87  	  if (mpz_cmp (r, rr) || mpz_cmp (q, rq))
    88  	    {
    89  	      fprintf (stderr, "mpz_%cdiv_qr failed:\n", name[j]);
    90  	      dump ("a", a);
    91  	      dump ("b", b);
    92  	      dump ("r   ", r);
    93  	      dump ("rref", rr);
    94  	      dump ("q   ", q);
    95  	      dump ("qref", rq);
    96  	      abort ();
    97  	    }
    98  	  mpz_set_si (q, -5);
    99  	  div_q[j] (q, a, b);
   100  	  if (mpz_cmp (q, rq))
   101  	    {
   102  	      fprintf (stderr, "mpz_%cdiv_q failed:\n", name[j]);
   103  	      dump ("a", a);
   104  	      dump ("b", b);
   105  	      dump ("q   ", q);
   106  	      dump ("qref", rq);
   107  	      abort ();
   108  	    }
   109  	  mpz_set_ui (r, ~5);
   110  	  div_r[j] (r, a, b);
   111  	  if (mpz_cmp (r, rr))
   112  	    {
   113  	      fprintf (stderr, "mpz_%cdiv_r failed:\n", name[j]);
   114  	      dump ("a", a);
   115  	      dump ("b", b);
   116  	      dump ("r   ", r);
   117  	      dump ("rref", rr);
   118  	      abort ();
   119  	    }
   120  
   121  	  if (j == 0)		/* do this once, not for all roundings */
   122  	    {
   123  	      div_p = mpz_divisible_p (a, b);
   124  	      if ((mpz_sgn (r) == 0) ^ (div_p != 0))
   125  		{
   126  		  fprintf (stderr, "mpz_divisible_p failed:\n");
   127  		  dump ("a", a);
   128  		  dump ("b", b);
   129  		  dump ("r   ", r);
   130  		  abort ();
   131  		}
   132  	    }
   133  
   134  	  if (j == 0 && mpz_sgn (b) < 0)  /* ceil, negative divisor */
   135  	    {
   136  	      mpz_mod (r, a, b);
   137  	      if (mpz_cmp (r, rr))
   138  		{
   139  		  fprintf (stderr, "mpz_mod failed:\n");
   140  		  dump ("a", a);
   141  		  dump ("b", b);
   142  		  dump ("r   ", r);
   143  		  dump ("rref", rr);
   144  		  abort ();
   145  		}
   146  	    }
   147  
   148  	  if (j == 1 && mpz_sgn (b) > 0) /* floor, positive divisor */
   149  	    {
   150  	      mpz_mod (r, a, b);
   151  	      if (mpz_cmp (r, rr))
   152  		{
   153  		  fprintf (stderr, "mpz_mod failed:\n");
   154  		  dump ("a", a);
   155  		  dump ("b", b);
   156  		  dump ("r   ", r);
   157  		  dump ("rref", rr);
   158  		  abort ();
   159  		}
   160  	    }
   161  
   162  	  if (mpz_fits_ulong_p (b))
   163  	    {
   164  	      mp_limb_t rl;
   165  
   166  	      rl = div_qr_ui[j] (q, r, a, mpz_get_ui (b));
   167  	      if (rl != mpz_get_ui (rr)
   168  		  || mpz_cmp (r, rr) || mpz_cmp (q, rq))
   169  		{
   170  		  fprintf (stderr, "mpz_%cdiv_qr_ui failed:\n", name[j]);
   171  		  dump ("a", a);
   172  		  dump ("b", b);
   173  		  fprintf(stderr, "rl   = %lx\n", rl);
   174  		  dump ("r   ", r);
   175  		  dump ("rref", rr);
   176  		  dump ("q   ", q);
   177  		  dump ("qref", rq);
   178  		  abort ();
   179  		}
   180  
   181  	      mpz_set_si (q, 3);
   182  	      rl = div_q_ui[j] (q, a, mpz_get_ui (b));
   183  	      if (rl != mpz_get_ui (rr) || mpz_cmp (q, rq))
   184  		{
   185  		  fprintf (stderr, "mpz_%cdiv_q_ui failed:\n", name[j]);
   186  		  dump ("a", a);
   187  		  dump ("b", b);
   188  		  fprintf(stderr, "rl   = %lx\n", rl);
   189  		  dump ("rref", rr);
   190  		  dump ("q   ", q);
   191  		  dump ("qref", rq);
   192  		  abort ();
   193  		}
   194  
   195  	      mpz_set_ui (r, 7);
   196  	      rl = div_r_ui[j] (r, a, mpz_get_ui (b));
   197  	      if (rl != mpz_get_ui (rr) || mpz_cmp (r, rr))
   198  		{
   199  		  fprintf (stderr, "mpz_%cdiv_qr_ui failed:\n", name[j]);
   200  		  dump ("a", a);
   201  		  dump ("b", b);
   202  		  fprintf(stderr, "rl   = %lx\n", rl);
   203  		  dump ("r   ", r);
   204  		  dump ("rref", rr);
   205  		  abort ();
   206  		}
   207  
   208  	      rl = div_ui[j] (a, mpz_get_ui (b));
   209  	      if (rl != mpz_get_ui (rr))
   210  		{
   211  		  fprintf (stderr, "mpz_%cdiv_qr_ui failed:\n", name[j]);
   212  		  dump ("a", a);
   213  		  dump ("b", b);
   214  		  fprintf(stderr, "rl   = %lx\n", rl);
   215  		  dump ("rref", rr);
   216  		  abort ();
   217  		}
   218  
   219  	      if (j == 0)	/* do this once, not for all roundings */
   220  		{
   221  		  div_p = mpz_divisible_ui_p (a, mpz_get_ui (b));
   222  		  if ((mpz_sgn (r) == 0) ^ (div_p != 0))
   223  		    {
   224  		      fprintf (stderr, "mpz_divisible_ui_p failed:\n");
   225  		      dump ("a", a);
   226  		      dump ("b", b);
   227  		      dump ("r   ", r);
   228  		      abort ();
   229  		    }
   230  		}
   231  
   232  	      if (j == 1)	/* floor */
   233  		{
   234  		  mpz_mod_ui (r, a, mpz_get_ui (b));
   235  		  if (mpz_cmp (r, rr))
   236  		    {
   237  		      fprintf (stderr, "mpz_mod failed:\n");
   238  		      dump ("a", a);
   239  		      dump ("b", b);
   240  		      dump ("r   ", r);
   241  		      dump ("rref", rr);
   242  		      abort ();
   243  		    }
   244  		}
   245  	    }
   246  	}
   247      }
   248    mpz_clear (a);
   249    mpz_clear (b);
   250    mpz_clear (r);
   251    mpz_clear (q);
   252    mpz_clear (rr);
   253    mpz_clear (rq);
   254  }