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

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