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

     1  /* Exercise some mpz_..._si functions.
     2  
     3  Copyright 2013, 2016 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  testmain (int argc, char *argv[])
   201  {
   202    try_fits_slong_p ();
   203    try_op_si (-1);
   204    try_op_si (1);
   205  }