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

     1  /* Test mpz_cmp_d and mpz_cmpabs_d.
     2  
     3  Copyright 2001-2003, 2005, 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 <math.h>
    21  
    22  #include "testutils.h"
    23  
    24  /* FIXME: Not sure if the tests here are exhaustive.  Ought to try to get
    25     each possible exit from mpz_cmp_d (and mpz_cmpabs_d) exercised.  */
    26  
    27  
    28  #define SGN(n)  ((n) > 0 ? 1 : (n) < 0 ? -1 : 0)
    29  
    30  
    31  void
    32  check_one (const char *name, mpz_srcptr x, double y, int cmp, int cmpabs)
    33  {
    34    int   got;
    35  
    36    got = mpz_cmp_d (x, y);
    37    if (SGN(got) != cmp)
    38      {
    39        unsigned i;
    40        printf    ("mpz_cmp_d wrong (from %s)\n", name);
    41        printf    ("  got  %d\n", got);
    42        printf    ("  want %d\n", cmp);
    43      fail:
    44        printf ("  x=");
    45        mpz_out_str (stdout, 10, x);
    46        printf    ("\n  y %g\n", y);
    47        printf ("  x=0x");
    48        mpz_out_str (stdout, -16, x);
    49        printf    ("\n  y %g\n", y);
    50        printf    ("  y");
    51        for (i = 0; i < sizeof(y); i++)
    52          printf (" %02X", (unsigned) ((unsigned char *) &y)[i]);
    53        printf ("\n");
    54        abort ();
    55      }
    56  
    57    got = mpz_cmpabs_d (x, y);
    58    if (SGN(got) != cmpabs)
    59      {
    60        printf    ("mpz_cmpabs_d wrong\n");
    61        printf    ("  got  %d\n", got);
    62        printf    ("  want %d\n", cmpabs);
    63        goto fail;
    64      }
    65  }
    66  
    67  void
    68  check_data (void)
    69  {
    70    static const struct {
    71      const char  *x;
    72      double      y;
    73      int         cmp, cmpabs;
    74  
    75    } data[] = {
    76  
    77      {  "0",  0.0,  0,  0 },
    78  
    79      {  "1",  0.0,  1,  1 },
    80      { "-1",  0.0, -1,  1 },
    81  
    82      {  "1",  0.5,  1,  1 },
    83      { "-1", -0.5, -1,  1 },
    84  
    85      {  "0",  1.0, -1, -1 },
    86      {  "0", -1.0,  1, -1 },
    87  
    88      {  "0x1000000000000000000000000000000000000000000000000", 1.0,  1, 1 },
    89      { "-0x1000000000000000000000000000000000000000000000000", 1.0, -1, 1 },
    90  
    91      {  "0",  1e100, -1, -1 },
    92      {  "0", -1e100,  1, -1 },
    93  
    94      {  "2",  1.5,   1,  1 },
    95      {  "2", -1.5,   1,  1 },
    96      { "-2",  1.5,  -1,  1 },
    97      { "-2", -1.5,  -1,  1 },
    98    };
    99  
   100    mpz_t    x;
   101    unsigned i;
   102  
   103    mpz_init (x);
   104  
   105    for (i = 0; i < numberof (data); i++)
   106      {
   107        mpz_set_str_or_abort (x, data[i].x, 0);
   108        check_one ("check_data", x, data[i].y, data[i].cmp, data[i].cmpabs);
   109      }
   110  
   111    mpz_clear (x);
   112  }
   113  
   114  
   115  /* Equality of integers with up to 53 bits */
   116  void
   117  check_onebits (void)
   118  {
   119    mpz_t   x, x2;
   120    double  y;
   121    int     i;
   122  
   123    mpz_init_set_ui (x, 0L);
   124    mpz_init (x2);
   125  
   126    for (i = 0; i < 512; i++)
   127      {
   128        mpz_mul_2exp (x, x, 1);
   129        mpz_add_ui (x, x, 1L);
   130  
   131        y = mpz_get_d (x);
   132        mpz_set_d (x2, y);
   133  
   134        /* stop if any truncation is occurring */
   135        if (mpz_cmp (x, x2) != 0)
   136          break;
   137  
   138        check_one ("check_onebits", x, y, 0, 0);
   139        check_one ("check_onebits", x, -y, 1, 0);
   140        mpz_neg (x, x);
   141        check_one ("check_onebits", x, y, -1, 0);
   142        check_one ("check_onebits", x, -y, 0, 0);
   143        mpz_neg (x, x);
   144      }
   145  
   146    mpz_clear (x);
   147    mpz_clear (x2);
   148  }
   149  
   150  
   151  /* With the mpz differing by 1, in a limb position possibly below the double */
   152  void
   153  check_low_z_one (void)
   154  {
   155    mpz_t          x;
   156    double         y;
   157    unsigned long  i;
   158  
   159    mpz_init (x);
   160  
   161    /* FIXME: It'd be better to base this on the float format. */
   162  #if defined (__vax) || defined (__vax__)
   163  #define LIM 127			/* vax fp numbers have limited range */
   164  #else
   165  #define LIM 512
   166  #endif
   167  
   168    for (i = 1; i < LIM; i++)
   169      {
   170        mpz_set_ui (x, 1L);
   171        mpz_mul_2exp (x, x, i);
   172        y = mpz_get_d (x);
   173  
   174        check_one ("check_low_z_one", x, y,   0, 0);
   175        check_one ("check_low_z_one", x, -y,  1, 0);
   176        mpz_neg (x, x);
   177        check_one ("check_low_z_one", x, y,  -1, 0);
   178        check_one ("check_low_z_one", x, -y,  0, 0);
   179        mpz_neg (x, x);
   180  
   181        mpz_sub_ui (x, x, 1);
   182  
   183        check_one ("check_low_z_one", x, y,  -1, -1);
   184        check_one ("check_low_z_one", x, -y,  1, -1);
   185        mpz_neg (x, x);
   186        check_one ("check_low_z_one", x, y,  -1, -1);
   187        check_one ("check_low_z_one", x, -y,  1, -1);
   188        mpz_neg (x, x);
   189  
   190        mpz_add_ui (x, x, 2);
   191  
   192        check_one ("check_low_z_one", x, y,   1, 1);
   193        check_one ("check_low_z_one", x, -y,  1, 1);
   194        mpz_neg (x, x);
   195        check_one ("check_low_z_one", x, y,  -1, 1);
   196        check_one ("check_low_z_one", x, -y, -1, 1);
   197        mpz_neg (x, x);
   198      }
   199  
   200    mpz_clear (x);
   201  }
   202  
   203  /* Comparing 1 and 1+2^-n.  "y" is volatile to make gcc store and fetch it,
   204     which forces it to a 64-bit double, whereas on x86 it would otherwise
   205     remain on the float stack as an 80-bit long double.  */
   206  void
   207  check_one_2exp (void)
   208  {
   209    double           e;
   210    mpz_t            x;
   211    volatile double  y;
   212    int              i;
   213  
   214    mpz_init (x);
   215  
   216    e = 1.0;
   217    for (i = 0; i < 128; i++)
   218      {
   219        e /= 2.0;
   220        y = 1.0 + e;
   221        if (y == 1.0)
   222          break;
   223  
   224        mpz_set_ui (x, 1L);
   225        check_one ("check_one_2exp", x,  y, -1, -1);
   226        check_one ("check_one_2exp", x, -y,  1, -1);
   227  
   228        mpz_set_si (x, -1L);
   229        check_one ("check_one_2exp", x,  y, -1, -1);
   230        check_one ("check_one_2exp", x, -y,  1, -1);
   231      }
   232  
   233    mpz_clear (x);
   234  }
   235  
   236  void
   237  check_infinity (void)
   238  {
   239    mpz_t   x;
   240    double  y = HUGE_VAL;
   241    if (y != 2*y)
   242      return;
   243  
   244    mpz_init (x);
   245  
   246    /* 0 cmp inf */
   247    mpz_set_ui (x, 0L);
   248    check_one ("check_infinity", x,  y, -1, -1);
   249    check_one ("check_infinity", x, -y,  1, -1);
   250  
   251    /* 123 cmp inf */
   252    mpz_set_ui (x, 123L);
   253    check_one ("check_infinity", x,  y, -1, -1);
   254    check_one ("check_infinity", x, -y,  1, -1);
   255  
   256    /* -123 cmp inf */
   257    mpz_set_si (x, -123L);
   258    check_one ("check_infinity", x,  y, -1, -1);
   259    check_one ("check_infinity", x, -y,  1, -1);
   260  
   261    /* 2^5000 cmp inf */
   262    mpz_set_ui (x, 1L);
   263    mpz_mul_2exp (x, x, 5000L);
   264    check_one ("check_infinity", x,  y, -1, -1);
   265    check_one ("check_infinity", x, -y,  1, -1);
   266  
   267    /* -2^5000 cmp inf */
   268    mpz_neg (x, x);
   269    check_one ("check_infinity", x,  y, -1, -1);
   270    check_one ("check_infinity", x, -y,  1, -1);
   271  
   272    mpz_clear (x);
   273  }
   274  
   275  void
   276  testmain (int argc, char *argv[])
   277  {
   278    check_data ();
   279    check_onebits ();
   280    check_low_z_one ();
   281    check_one_2exp ();
   282    check_infinity ();
   283  }