(root)/
gmp-6.3.0/
tests/
mpf/
t-get_si.c
       1  /* Exercise mpz_get_si.
       2  
       3  Copyright 2000, 2001 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 "gmp-impl.h"
      23  #include "tests.h"
      24  
      25  
      26  void
      27  check_data (void)
      28  {
      29    static const struct {
      30      int         base;
      31      const char  *f;
      32      long        want;
      33    } data[] = {
      34      { 10, "0",      0L },
      35      { 10, "1",      1L },
      36      { 10, "-1",     -1L },
      37      { 10, "2",      2L },
      38      { 10, "-2",     -2L },
      39      { 10, "12345",  12345L },
      40      { 10, "-12345", -12345L },
      41  
      42      /* fraction bits ignored */
      43      { 10, "0.5",    0L },
      44      { 10, "-0.5",   0L },
      45      { 10, "1.1",    1L },
      46      { 10, "-1.1",   -1L },
      47      { 10, "1.9",    1L },
      48      { 10, "-1.9",   -1L },
      49      { 16, "1.000000000000000000000000000000000000000000000000001", 1L },
      50      { 16, "-1.000000000000000000000000000000000000000000000000001", -1L },
      51  
      52      /* low bits extracted (this is undocumented) */
      53      { 16, "1000000000000000000000000000000000000000000000000001", 1L },
      54      { 16, "-1000000000000000000000000000000000000000000000000001", -1L },
      55    };
      56  
      57    int    i;
      58    mpf_t  f;
      59    long   got;
      60  
      61    mpf_init2 (f, 2000L);
      62    for (i = 0; i < numberof (data); i++)
      63      {
      64        mpf_set_str_or_abort (f, data[i].f, data[i].base);
      65  
      66        got = mpf_get_si (f);
      67        if (got != data[i].want)
      68  	{
      69  	  printf ("mpf_get_si wrong at data[%d]\n", i);
      70  	  printf ("   f     \"%s\"\n", data[i].f);
      71  	  printf ("     dec "); mpf_out_str (stdout, 10, 0, f); printf ("\n");
      72  	  printf ("     hex "); mpf_out_str (stdout, 16, 0, f); printf ("\n");
      73  	  printf ("     size %ld\n", (long) SIZ(f));
      74  	  printf ("     exp  %ld\n", (long) EXP(f));
      75  	  printf ("   got   %ld (0x%lX)\n", got, got);
      76  	  printf ("   want  %ld (0x%lX)\n", data[i].want, data[i].want);
      77  	  abort();
      78  	}
      79      }
      80    mpf_clear (f);
      81  }
      82  
      83  
      84  void
      85  check_max (void)
      86  {
      87    mpf_t  f;
      88    long   want;
      89    long   got;
      90  
      91    mpf_init2 (f, 200L);
      92  
      93  #define CHECK_MAX(name)                                         \
      94    if (got != want)                                              \
      95      {                                                           \
      96        printf ("mpf_get_si wrong on %s\n", name);                \
      97        printf ("   f    ");                                      \
      98        mpf_out_str (stdout, 10, 0, f); printf (", hex ");        \
      99        mpf_out_str (stdout, 16, 0, f); printf ("\n");            \
     100        printf ("   got  %ld, hex %lX\n", got, got);              \
     101        printf ("   want %ld, hex %lX\n", want, want);            \
     102        abort();                                                  \
     103      }
     104  
     105    want = LONG_MAX;
     106    mpf_set_si (f, want);
     107    got = mpf_get_si (f);
     108    CHECK_MAX ("LONG_MAX");
     109  
     110    want = LONG_MIN;
     111    mpf_set_si (f, want);
     112    got = mpf_get_si (f);
     113    CHECK_MAX ("LONG_MIN");
     114  
     115    mpf_clear (f);
     116  }
     117  
     118  
     119  void
     120  check_limbdata (void)
     121  {
     122  #define M  GMP_NUMB_MAX
     123  
     124    static const struct {
     125      mp_exp_t       exp;
     126      mp_size_t      size;
     127      mp_limb_t      d[10];
     128      unsigned long  want;
     129  
     130    } data[] = {
     131  
     132      /* in the comments here, a "_" indicates a digit (ie. limb) position not
     133         included in the d data, and therefore zero */
     134  
     135      { 0, 0, { 0 }, 0L },    /* 0 */
     136  
     137      { 1,  1, { 1 }, 1L },   /* 1 */
     138      { 1, -1, { 1 }, -1UL },  /* -1 */
     139  
     140      { 0,  1, { 1 }, 0L },   /* .1 */
     141      { 0, -1, { 1 }, 0L },   /* -.1 */
     142  
     143      { -1,  1, { 1 }, 0L },  /* ._1 */
     144      { -1, -1, { 1 }, 0L },  /* -._1 */
     145  
     146      { -999,          1, { 1 }, 0L },   /* .___1 small */
     147      { MP_EXP_T_MIN,  1, { 1 }, 0L },   /* .____1 very small */
     148  
     149      { 999,          1, { 1 }, 0L },    /* 1____. big */
     150      { MP_EXP_T_MAX, 1, { 1 }, 0L },    /* 1_____. very big */
     151  
     152      { 1, 2, { 999, 2 }, 2L },                  /* 2.9 */
     153      { 5, 8, { 7, 8, 9, 3, 0, 0, 0, 1 }, 3L },  /* 10003.987 */
     154  
     155      { 2, 2, { M, M },    LONG_MAX }, /* FF. */
     156      { 2, 2, { M, M, M }, LONG_MAX }, /* FF.F */
     157      { 3, 3, { M, M, M }, LONG_MAX }, /* FFF. */
     158  
     159  #if GMP_NUMB_BITS >= BITS_PER_ULONG
     160      /* normal case, numb bigger than long */
     161      { 2,  1, { 1 },    0L },      /* 1_. */
     162      { 2,  2, { 0, 1 }, 0L },      /* 10. */
     163      { 2,  2, { 999, 1 }, 999L },  /* 19. */
     164      { 3,  2, { 999, 1 }, 0L },    /* 19_. */
     165  
     166  #else
     167      /* nails case, numb smaller than long */
     168      { 2,  1, { 1 }, 1L << GMP_NUMB_BITS },  /* 1_. */
     169      { 3,  1, { 1 }, 0L },                   /* 1__. */
     170  
     171      { 2,  2, { 99, 1 },    99L + (1L << GMP_NUMB_BITS) },  /* 19. */
     172      { 3,  2, { 1, 99 },    1L << GMP_NUMB_BITS },          /* 91_. */
     173      { 3,  3, { 0, 1, 99 }, 1L << GMP_NUMB_BITS },          /* 910. */
     174  
     175  #endif
     176    };
     177  
     178    mpf_t          f;
     179    unsigned long  got;
     180    int            i;
     181    mp_limb_t      buf[20 + numberof(data[i].d)];
     182  
     183    for (i = 0; i < numberof (data); i++)
     184      {
     185        refmpn_fill (buf, 10, CNST_LIMB(0xDEADBEEF));
     186        refmpn_copy (buf+10, data[i].d, ABS(data[i].size));
     187        refmpn_fill (buf+10+ABS(data[i].size), 10, CNST_LIMB(0xDEADBEEF));
     188  
     189        PTR(f) = buf+10;
     190        EXP(f) = data[i].exp;
     191        SIZ(f) = data[i].size;
     192        PREC(f) = numberof (data[i].d);
     193        MPF_CHECK_FORMAT (f);
     194  
     195        got = mpf_get_si (f);
     196        if (got != data[i].want)
     197  	{
     198  	  printf    ("mpf_get_si wrong at limb data[%d]\n", i);
     199  	  mpf_trace ("  f", f);
     200  	  mpn_trace ("  d", data[i].d, data[i].size);
     201  	  printf    ("  size %ld\n", (long) data[i].size);
     202  	  printf    ("  exp %ld\n", (long) data[i].exp);
     203  	  printf    ("  got   %lu (0x%lX)\n", got, got);
     204  	  printf    ("  want  %lu (0x%lX)\n", data[i].want, data[i].want);
     205  	  abort();
     206  	}
     207      }
     208  }
     209  
     210  
     211  int
     212  main (void)
     213  {
     214    tests_start ();
     215  
     216    check_data ();
     217    check_max ();
     218    check_limbdata ();
     219  
     220    tests_end ();
     221    exit (0);
     222  }