(root)/
gmp-6.3.0/
mini-gmp/
tests/
t-div.c
       1  /*
       2  
       3  Copyright 2012, 2013, 2018 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 * const 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 * const 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 * const div_r_ui[3] =
      77  	    {
      78  	      mpz_cdiv_r_ui, mpz_fdiv_r_ui, mpz_tdiv_r_ui
      79  	    };
      80  	  static div_ui_func * const 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  	  mpz_set_si (r, -6);
     135  	  if (j == 0 && mpz_sgn (b) < 0)  /* ceil, negative divisor */
     136  	    {
     137  	      mpz_mod (r, a, b);
     138  	      if (mpz_cmp (r, rr))
     139  		{
     140  		  fprintf (stderr, "mpz_mod failed:\n");
     141  		  dump ("a", a);
     142  		  dump ("b", b);
     143  		  dump ("r   ", r);
     144  		  dump ("rref", rr);
     145  		  abort ();
     146  		}
     147  	    }
     148  
     149  	  if (j == 1 && mpz_sgn (b) > 0) /* floor, positive divisor */
     150  	    {
     151  	      mpz_mod (r, a, b);
     152  	      if (mpz_cmp (r, rr))
     153  		{
     154  		  fprintf (stderr, "mpz_mod failed:\n");
     155  		  dump ("a", a);
     156  		  dump ("b", b);
     157  		  dump ("r   ", r);
     158  		  dump ("rref", rr);
     159  		  abort ();
     160  		}
     161  	    }
     162  
     163  	  if (mpz_fits_ulong_p (b))
     164  	    {
     165  	      unsigned long rl;
     166  
     167  	      mpz_set_si (r, -7);
     168  	      mpz_set_ui (q, ~7);
     169  	      rl = div_qr_ui[j] (q, r, a, mpz_get_ui (b));
     170  	      if (rl != mpz_get_ui (rr)
     171  		  || mpz_cmp (r, rr) || mpz_cmp (q, rq))
     172  		{
     173  		  fprintf (stderr, "mpz_%cdiv_qr_ui failed:\n", name[j]);
     174  		  dump ("a", a);
     175  		  dump ("b", b);
     176  		  fprintf(stderr, "rl   = %lx\n", rl);
     177  		  dump ("r   ", r);
     178  		  dump ("rref", rr);
     179  		  dump ("q   ", q);
     180  		  dump ("qref", rq);
     181  		  abort ();
     182  		}
     183  
     184  	      mpz_set_si (q, 3);
     185  	      rl = div_q_ui[j] (q, a, mpz_get_ui (b));
     186  	      if (rl != mpz_get_ui (rr) || mpz_cmp (q, rq))
     187  		{
     188  		  fprintf (stderr, "mpz_%cdiv_q_ui failed:\n", name[j]);
     189  		  dump ("a", a);
     190  		  dump ("b", b);
     191  		  fprintf(stderr, "rl   = %lx\n", rl);
     192  		  dump ("rref", rr);
     193  		  dump ("q   ", q);
     194  		  dump ("qref", rq);
     195  		  abort ();
     196  		}
     197  
     198  	      mpz_set_ui (r, 7);
     199  	      rl = div_r_ui[j] (r, a, mpz_get_ui (b));
     200  	      if (rl != mpz_get_ui (rr) || mpz_cmp (r, rr))
     201  		{
     202  		  fprintf (stderr, "mpz_%cdiv_r_ui failed:\n", name[j]);
     203  		  dump ("a", a);
     204  		  dump ("b", b);
     205  		  fprintf(stderr, "rl   = %lx\n", rl);
     206  		  dump ("r   ", r);
     207  		  dump ("rref", rr);
     208  		  abort ();
     209  		}
     210  
     211  	      rl = div_ui[j] (a, mpz_get_ui (b));
     212  	      if (rl != mpz_get_ui (rr))
     213  		{
     214  		  fprintf (stderr, "mpz_%cdiv_ui failed:\n", name[j]);
     215  		  dump ("a", a);
     216  		  dump ("b", b);
     217  		  fprintf(stderr, "rl   = %lx\n", rl);
     218  		  dump ("rref", rr);
     219  		  abort ();
     220  		}
     221  
     222  	      if (j == 0)	/* do this once, not for all roundings */
     223  		{
     224  		  div_p = mpz_divisible_ui_p (a, mpz_get_ui (b));
     225  		  if ((mpz_sgn (r) == 0) ^ (div_p != 0))
     226  		    {
     227  		      fprintf (stderr, "mpz_divisible_ui_p failed:\n");
     228  		      dump ("a", a);
     229  		      dump ("b", b);
     230  		      dump ("r   ", r);
     231  		      abort ();
     232  		    }
     233  		}
     234  
     235  	      if (j == 1)	/* floor */
     236  		{
     237  		  mpz_set_si (r, -2);
     238  		  mpz_mod_ui (r, a, mpz_get_ui (b));
     239  		  if (mpz_cmp (r, rr))
     240  		    {
     241  		      fprintf (stderr, "mpz_mod failed:\n");
     242  		      dump ("a", a);
     243  		      dump ("b", b);
     244  		      dump ("r   ", r);
     245  		      dump ("rref", rr);
     246  		      abort ();
     247  		    }
     248  		}
     249  	    }
     250  	}
     251      }
     252    mpz_clear (a);
     253    mpz_clear (b);
     254    mpz_clear (r);
     255    mpz_clear (q);
     256    mpz_clear (rr);
     257    mpz_clear (rq);
     258  }