(root)/
gmp-6.3.0/
tests/
mpz/
t-divis.c
       1  /* test mpz_divisible_p and mpz_divisible_ui_p
       2  
       3  Copyright 2001, 2009 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 <stdio.h>
      21  #include <stdlib.h>
      22  
      23  #include "gmp-impl.h"
      24  #include "tests.h"
      25  
      26  
      27  void
      28  check_one (mpz_srcptr a, mpz_srcptr d, int want)
      29  {
      30    int   got;
      31  
      32    if (mpz_fits_ulong_p (d))
      33      {
      34        unsigned long  u = mpz_get_ui (d);
      35        got = (mpz_divisible_ui_p (a, u) != 0);
      36        if (want != got)
      37          {
      38            printf ("mpz_divisible_ui_p wrong\n");
      39            printf ("   expected %d got %d\n", want, got);
      40            mpz_trace ("   a", a);
      41            printf ("   d=%lu\n", u);
      42            mp_trace_base = -16;
      43            mpz_trace ("   a", a);
      44            printf ("   d=0x%lX\n", u);
      45            abort ();
      46          }
      47      }
      48  
      49    got = (mpz_divisible_p (a, d) != 0);
      50    if (want != got)
      51      {
      52        printf ("mpz_divisible_p wrong\n");
      53        printf ("   expected %d got %d\n", want, got);
      54        mpz_trace ("   a", a);
      55        mpz_trace ("   d", d);
      56        mp_trace_base = -16;
      57        mpz_trace ("   a", a);
      58        mpz_trace ("   d", d);
      59        abort ();
      60      }
      61  }
      62  
      63  void
      64  check_data (void)
      65  {
      66    static const struct {
      67      const char *a;
      68      const char *d;
      69      int        want;
      70  
      71    } data[] = {
      72  
      73      { "0",    "0", 1 },
      74      { "17",   "0", 0 },
      75      { "0",    "1", 1 },
      76      { "123",  "1", 1 },
      77      { "-123", "1", 1 },
      78  
      79      { "0",  "2", 1 },
      80      { "1",  "2", 0 },
      81      { "2",  "2", 1 },
      82      { "-2", "2", 1 },
      83      { "0x100000000000000000000000000000000", "2", 1 },
      84      { "0x100000000000000000000000000000001", "2", 0 },
      85  
      86      { "0x3333333333333333", "3", 1 },
      87      { "0x3333333333333332", "3", 0 },
      88      { "0x33333333333333333333333333333333", "3", 1 },
      89      { "0x33333333333333333333333333333332", "3", 0 },
      90  
      91      /* divisor changes from 2 to 1 limb after stripping 2s */
      92      {          "0x3333333300000000",         "0x180000000",         1 },
      93      {  "0x33333333333333330000000000000000", "0x18000000000000000", 1 },
      94      { "0x133333333333333330000000000000000", "0x18000000000000000", 0 },
      95    };
      96  
      97    mpz_t   a, d;
      98    int     i;
      99  
     100    mpz_init (a);
     101    mpz_init (d);
     102  
     103    for (i = 0; i < numberof (data); i++)
     104      {
     105        mpz_set_str_or_abort (a, data[i].a, 0);
     106        mpz_set_str_or_abort (d, data[i].d, 0);
     107        check_one (a, d, data[i].want);
     108      }
     109  
     110    mpz_clear (a);
     111    mpz_clear (d);
     112  }
     113  
     114  void
     115  check_random (int reps)
     116  {
     117    gmp_randstate_ptr rands = RANDS;
     118    mpz_t   a, d, r;
     119    int     i;
     120    int     want;
     121  
     122    mpz_init (a);
     123    mpz_init (d);
     124    mpz_init (r);
     125  
     126    for (i = 0; i < reps; i++)
     127      {
     128        mpz_erandomb (a, rands, 1 << 19);
     129        mpz_erandomb_nonzero (d, rands, 1 << 18);
     130  
     131        mpz_fdiv_r (r, a, d);
     132  
     133        want = (mpz_sgn (r) == 0);
     134        check_one (a, d, want);
     135  
     136        mpz_sub (a, a, r);
     137        check_one (a, d, 1);
     138  
     139        if (mpz_cmpabs_ui (d, 1L) == 0)
     140          continue;
     141  
     142        mpz_add_ui (a, a, 1L);
     143        check_one (a, d, 0);
     144      }
     145  
     146    mpz_clear (a);
     147    mpz_clear (d);
     148    mpz_clear (r);
     149  }
     150  
     151  
     152  int
     153  main (int argc, char *argv[])
     154  {
     155    int  reps = 100;
     156  
     157    tests_start ();
     158  
     159    TESTS_REPS (reps, argv, argc);
     160  
     161    check_data ();
     162    check_random (reps);
     163  
     164    tests_end ();
     165    exit (0);
     166  }