(root)/
gmp-6.3.0/
mini-gmp/
tests/
t-signed.c
       1  /* Exercise some mpz_..._si functions.
       2  
       3  Copyright 2013, 2016, 2020 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 <limits.h>
      21  #include <stdio.h>
      22  #include <stdlib.h>
      23  
      24  #include "testutils.h"
      25  
      26  /* Always called with sz fitting in a signed long, and si is the
      27     corresponding value. */
      28  int
      29  check_si (const mpz_t sz, long si)
      30  {
      31    mpz_t t;
      32  
      33    /* Checks on sz/si */
      34    if ((mpz_cmp_si (sz, si)) != 0)
      35      {
      36        printf ("mpz_cmp_si (sz, %ld) != 0.\n", si);
      37        return 0;
      38      }
      39    if (mpz_get_si (sz) != si)
      40      {
      41        printf ("mpz_get_si (sz) != %ld.\n", si);
      42        return 0;
      43      }
      44  
      45    mpz_init_set_si (t, si);
      46  
      47    if (mpz_cmp (t, sz) != 0)
      48      {
      49        printf ("mpz_init_set_si (%ld) failed.\n", si);
      50        printf (" got="); mpz_out_str (stdout, 10, t); printf ("\n");
      51        return 0;
      52      }
      53  
      54    mpz_clear (t);
      55    return 1;
      56  }
      57  
      58  /* Called with mpz_cmp (sz, oz) == c. If sz fits in a signed long,
      59     si is the coresponding value, and similarly for oz and oi. */
      60  void
      61  check_si_cmp (const mpz_t sz, const mpz_t oz, long si, long oi, int c)
      62  {
      63    if (mpz_cmp (sz, oz) != c)
      64      {
      65        printf ("mpz_cmp (sz, oz) != %i.\n", c);
      66        goto fail;
      67      }
      68  
      69    if (mpz_fits_slong_p (sz))
      70      {
      71        if (!check_si (sz, si))
      72  	goto fail;
      73        if (mpz_cmp_si (oz, si) != -c)
      74  	{
      75  	  printf ("mpz_cmp_si (oz, %ld) != %i.\n", si, -c);
      76  	  goto fail;
      77  	}
      78      }
      79    else
      80      {
      81        if (mpz_cmp_si (sz, si) != c)
      82  	{
      83  	  printf ("mpz_cmp_si (sz, %ld) != %i.\n", si, c);
      84  	  goto fail;
      85  	}
      86        if (mpz_cmp_si (sz, -c) != c)
      87  	{
      88  	  printf ("mpz_cmp_si (sz, %i) != %i.\n", -c, c);
      89  	  goto fail;
      90  	}
      91      }
      92    if (mpz_fits_slong_p (oz))
      93      {
      94        if (!check_si (oz, oi))
      95  	goto fail;
      96        if (mpz_cmp_si (sz, oi) != c)
      97  	{
      98  	  printf ("mpz_cmp_si (sz, %ld) != %i.\n", oi, c);
      99  	  goto fail;
     100  	}
     101      }
     102    return;
     103  
     104   fail:
     105    printf (" sz="); mpz_out_str (stdout, 10, sz); printf ("\n");
     106    printf (" si=%ld\n", si);
     107    printf (" oz="); mpz_out_str (stdout, 10, oz); printf ("\n");
     108    printf (" oi=%ld\n", si);
     109    abort ();
     110  }
     111  
     112  void
     113  try_op_si (int c)
     114  {
     115    long  si, oi;
     116    mpz_t sz, oz;
     117    unsigned overflow_count;
     118  
     119    si = c;
     120    mpz_init_set_si (sz, si);
     121  
     122    oi = si;
     123    mpz_init_set (oz, sz);
     124  
     125    /* To get a few tests with operands straddling the border, don't
     126       stop at the very first operand exceeding a signed long. */
     127    for (overflow_count = 0; overflow_count < 10; )
     128      {
     129        /* c * 2^k */
     130        mpz_mul_2exp (sz, sz, 1);
     131        if (mpz_fits_slong_p (sz))
     132  	si *= 2;
     133        else
     134  	overflow_count++;
     135  
     136        check_si_cmp (sz, oz, si, oi, c);
     137  
     138        /* c * (2^k + 1) */
     139        if (c == -1)
     140  	mpz_sub_ui (oz, sz, 1);
     141        else
     142  	mpz_add_ui (oz, sz, 1);
     143        if (mpz_fits_slong_p (oz))
     144  	oi = si + c;
     145        else
     146  	overflow_count++;
     147        check_si_cmp (oz, sz, oi, si, c);
     148  
     149        /* c * (2^K - 1) */
     150        mpz_mul_si (oz, sz, 2*c);
     151        if (c == -1)
     152  	mpz_ui_sub (oz, 1, oz); /* oz = sz * 2 + 1 */
     153        else
     154  	mpz_sub_ui (oz, oz, 1); /* oz = sz * 2 - 1 */
     155        if (mpz_fits_slong_p (oz))
     156  	oi = (si - c) * 2 + c;
     157        else
     158  	overflow_count++;
     159  
     160        check_si_cmp (oz, sz, oi, si, c);
     161      };
     162  
     163    mpz_clear (sz);
     164    mpz_clear (oz);
     165  }
     166  
     167  void
     168  try_fits_slong_p (void)
     169  {
     170    mpz_t x;
     171    mpz_init_set_si (x, LONG_MAX);
     172    if (!mpz_fits_slong_p (x))
     173      {
     174        printf ("mpz_fits_slong_p (LONG_MAX) false!\n");
     175        abort ();
     176      }
     177    mpz_add_ui (x, x, 1);
     178    if (mpz_fits_slong_p (x))
     179      {
     180        printf ("mpz_fits_slong_p (LONG_MAX + 1) true!\n");
     181        abort ();
     182      }
     183    mpz_set_si (x, LONG_MIN);
     184    if (!mpz_fits_slong_p (x))
     185      {
     186        printf ("mpz_fits_slong_p (LONG_MIN) false!\n");
     187        abort ();
     188      }
     189    mpz_sub_ui (x, x, 1);
     190    if (mpz_fits_slong_p (x))
     191      {
     192        printf ("mpz_fits_slong_p (LONG_MIN - 1) true!\n");
     193        abort ();
     194      }
     195  
     196    mpz_clear (x);
     197  }
     198  
     199  void
     200  try_fits_utype_p (void)
     201  {
     202    mpz_t x;
     203    mpz_init (x);
     204    if (!mpz_fits_ulong_p (x))
     205      {
     206        printf ("mpz_fits_ulong_p (0) false!\n");
     207        abort ();
     208      }
     209    if (!mpz_fits_uint_p (x))
     210      {
     211        printf ("mpz_fits_uint_p (0) false!\n");
     212        abort ();
     213      }
     214    if (!mpz_fits_ushort_p (x))
     215      {
     216        printf ("mpz_fits_udhort_p (0) false!\n");
     217        abort ();
     218      }
     219    mpz_set_si (x, -1);
     220    if (mpz_fits_ulong_p (x))
     221      {
     222        printf ("mpz_fits_ulong_p (- 1) true!\n");
     223        abort ();
     224      }
     225    if (mpz_fits_uint_p (x))
     226      {
     227        printf ("mpz_fits_uint_p (- 1) true!\n");
     228        abort ();
     229      }
     230    if (mpz_fits_ushort_p (x))
     231      {
     232        printf ("mpz_fits_ushort_p (- 1) true!\n");
     233        abort ();
     234      }
     235    mpz_set_ui (x, ULONG_MAX);
     236    if (!mpz_fits_ulong_p (x))
     237      {
     238        printf ("mpz_fits_ulong_p (ULONG_MAX) false!\n");
     239        abort ();
     240      }
     241    mpz_add_ui (x, x, 1);
     242    if (mpz_fits_ulong_p (x))
     243      {
     244        printf ("mpz_fits_ulong_p (ULONG_MAX + 1) true!\n");
     245        abort ();
     246      }
     247    mpz_set_ui (x, UINT_MAX);
     248    if (!mpz_fits_uint_p (x))
     249      {
     250        printf ("mpz_fits_uint_p (UINT_MAX) false!\n");
     251        abort ();
     252      }
     253    mpz_add_ui (x, x, 1);
     254    if (mpz_fits_uint_p (x))
     255      {
     256        printf ("mpz_fits_uint_p (UINT_MAX + 1) true!\n");
     257        abort ();
     258      }
     259    mpz_set_ui (x, USHRT_MAX);
     260    if (!mpz_fits_ushort_p (x))
     261      {
     262        printf ("mpz_fits_ushort_p (USHRT_MAX) false!\n");
     263        abort ();
     264      }
     265    mpz_add_ui (x, x, 1);
     266    if (mpz_fits_ushort_p (x))
     267      {
     268        printf ("mpz_fits_ushort_p (USHRT_MAX + 1) true!\n");
     269        abort ();
     270      }
     271  
     272    mpz_clear (x);
     273  }
     274  
     275  void
     276  try_fits_sint_p (void)
     277  {
     278    mpz_t x;
     279    mpz_init_set_si (x, INT_MAX);
     280    if (!mpz_fits_sint_p (x))
     281      {
     282        printf ("mpz_fits_sint_p (INT_MAX) false!\n");
     283        abort ();
     284      }
     285    mpz_add_ui (x, x, 1);
     286    if (mpz_fits_sint_p (x))
     287      {
     288        printf ("mpz_fits_sint_p (INT_MAX + 1) true!\n");
     289        abort ();
     290      }
     291    mpz_set_si (x, INT_MIN);
     292    if (!mpz_fits_sint_p (x))
     293      {
     294        printf ("mpz_fits_sint_p (INT_MIN) false!\n");
     295        abort ();
     296      }
     297    mpz_sub_ui (x, x, 1);
     298    if (mpz_fits_sint_p (x))
     299      {
     300        printf ("mpz_fits_sint_p (INT_MIN - 1) true!\n");
     301        abort ();
     302      }
     303  
     304    mpz_clear (x);
     305  }
     306  
     307  void
     308  try_fits_sshort_p (void)
     309  {
     310    mpz_t x;
     311    mpz_init_set_si (x, SHRT_MAX);
     312    if (!mpz_fits_sshort_p (x))
     313      {
     314        printf ("mpz_fits_sshort_p (SHRT_MAX) false!\n");
     315        abort ();
     316      }
     317    mpz_add_ui (x, x, 1);
     318    if (mpz_fits_sshort_p (x))
     319      {
     320        printf ("mpz_fits_sshort_p (SHRT_MAX + 1) true!\n");
     321        abort ();
     322      }
     323    mpz_set_si (x, SHRT_MIN);
     324    if (!mpz_fits_sshort_p (x))
     325      {
     326        printf ("mpz_fits_sshort_p (SHRT_MIN) false!\n");
     327        abort ();
     328      }
     329    mpz_sub_ui (x, x, 1);
     330    if (mpz_fits_sshort_p (x))
     331      {
     332        printf ("mpz_fits_sshort_p (SHRT_MIN - 1) true!\n");
     333        abort ();
     334      }
     335  
     336    mpz_clear (x);
     337  }
     338  
     339  void
     340  testmain (int argc, char *argv[])
     341  {
     342    try_fits_slong_p ();
     343    try_fits_sint_p ();
     344    try_fits_sshort_p ();
     345    try_fits_utype_p ();
     346    try_op_si (-1);
     347    try_op_si (1);
     348  }