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

     1  /* Test mpf_trunc, mpf_ceil, mpf_floor.
     2  
     3  Copyright 2001, 2002 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.h"
    23  #include "gmp-impl.h"
    24  #include "tests.h"
    25  
    26  
    27  void
    28  check_print (mpf_srcptr src, mpf_srcptr got, mpf_srcptr want)
    29  {
    30    mp_trace_base = 16;
    31    mpf_trace ("src ", src);
    32    mpf_trace ("got ", got);
    33    mpf_trace ("want", want);
    34  
    35    printf ("got  size=%d exp=%ld\n", SIZ(got), EXP(got));
    36    mpn_trace ("     limbs=", PTR(got), (mp_size_t) ABSIZ(got));
    37  
    38    printf ("want size=%d exp=%ld\n", SIZ(want), EXP(want));
    39    mpn_trace ("     limbs=", PTR(want), (mp_size_t) ABSIZ(want));
    40  }
    41  
    42  void
    43  check_one (mpf_srcptr src, mpf_srcptr trunc, mpf_srcptr ceil, mpf_srcptr floor)
    44  {
    45    mpf_t  got;
    46  
    47    mpf_init2 (got, mpf_get_prec (trunc));
    48    ASSERT_ALWAYS (PREC(got) == PREC(trunc));
    49    ASSERT_ALWAYS (PREC(got) == PREC(ceil));
    50    ASSERT_ALWAYS (PREC(got) == PREC(floor));
    51  
    52  #define CHECK_SEP(name, fun, want)              \
    53    mpf_set_ui (got, 54321L); /* initial junk */  \
    54    fun (got, src);                               \
    55    MPF_CHECK_FORMAT (got);                       \
    56    if (mpf_cmp (got, want) != 0)                 \
    57      {                                           \
    58  	printf ("%s wrong\n", name);            \
    59  	check_print (src, got, want);           \
    60  	abort ();                               \
    61      }
    62  
    63    CHECK_SEP ("mpf_trunc", mpf_trunc, trunc);
    64    CHECK_SEP ("mpf_ceil",  mpf_ceil,  ceil);
    65    CHECK_SEP ("mpf_floor", mpf_floor, floor);
    66  
    67  #define CHECK_INPLACE(name, fun, want)  \
    68    mpf_set (got, src);                   \
    69    fun (got, got);                       \
    70    MPF_CHECK_FORMAT (got);               \
    71    if (mpf_cmp (got, want) != 0)         \
    72      {                                   \
    73  	printf ("%s wrong\n", name);    \
    74  	check_print (src, got, want);   \
    75  	abort ();                       \
    76      }
    77  
    78    CHECK_INPLACE ("mpf_trunc", mpf_trunc, trunc);
    79  
    80    /* Can't do these unconditionally in case truncation by mpf_set strips
    81       some low non-zero limbs which would have rounded the result.  */
    82    if (ABSIZ(src) <= PREC(trunc)+1)
    83      {
    84        CHECK_INPLACE ("mpf_ceil",  mpf_ceil,  ceil);
    85        CHECK_INPLACE ("mpf_floor", mpf_floor, floor);
    86      }
    87  
    88    mpf_clear (got);
    89  }
    90  
    91  void
    92  check_all (mpf_ptr src, mpf_ptr trunc, mpf_ptr ceil, mpf_ptr floor)
    93  {
    94    /* some of these values are generated with direct field assignments */
    95    MPF_CHECK_FORMAT (src);
    96    MPF_CHECK_FORMAT (trunc);
    97    MPF_CHECK_FORMAT (ceil);
    98    MPF_CHECK_FORMAT (floor);
    99  
   100    check_one (src, trunc, ceil, floor);
   101  
   102    mpf_neg (src,   src);
   103    mpf_neg (trunc, trunc);
   104    mpf_neg (ceil,  ceil);
   105    mpf_neg (floor, floor);
   106    check_one (src, trunc, floor, ceil);
   107  }
   108  
   109  void
   110  check_various (void)
   111  {
   112    mpf_t  src, trunc, ceil, floor;
   113    int    n, i;
   114  
   115    mpf_init2 (src, 512L);
   116    mpf_init2 (trunc, 256L);
   117    mpf_init2 (ceil,  256L);
   118    mpf_init2 (floor, 256L);
   119  
   120    /* 0 */
   121    mpf_set_ui (src, 0L);
   122    mpf_set_ui (trunc, 0L);
   123    mpf_set_ui (ceil, 0L);
   124    mpf_set_ui (floor, 0L);
   125    check_all (src, trunc, ceil, floor);
   126  
   127    /* 1 */
   128    mpf_set_ui (src, 1L);
   129    mpf_set_ui (trunc, 1L);
   130    mpf_set_ui (ceil, 1L);
   131    mpf_set_ui (floor, 1L);
   132    check_all (src, trunc, ceil, floor);
   133  
   134    /* 2^1024 */
   135    mpf_set_ui (src, 1L);
   136    mpf_mul_2exp (src,   src,   1024L);
   137    mpf_set (trunc, src);
   138    mpf_set (ceil,  src);
   139    mpf_set (floor, src);
   140    check_all (src, trunc, ceil, floor);
   141  
   142    /* 1/2^1024, fraction only */
   143    mpf_set_ui (src, 1L);
   144    mpf_div_2exp (src,  src, 1024L);
   145    mpf_set_si (trunc, 0L);
   146    mpf_set_si (ceil, 1L);
   147    mpf_set_si (floor, 0L);
   148    check_all (src, trunc, ceil, floor);
   149  
   150    /* 1/2 */
   151    mpf_set_ui (src, 1L);
   152    mpf_div_2exp (src,  src, 1L);
   153    mpf_set_si (trunc, 0L);
   154    mpf_set_si (ceil, 1L);
   155    mpf_set_si (floor, 0L);
   156    check_all (src, trunc, ceil, floor);
   157  
   158    /* 123+1/2^64 */
   159    mpf_set_ui (src, 1L);
   160    mpf_div_2exp (src,  src, 64L);
   161    mpf_add_ui (src,  src, 123L);
   162    mpf_set_si (trunc, 123L);
   163    mpf_set_si (ceil, 124L);
   164    mpf_set_si (floor, 123L);
   165    check_all (src, trunc, ceil, floor);
   166  
   167    /* integer of full prec+1 limbs, unchanged */
   168    n = PREC(trunc)+1;
   169    ASSERT_ALWAYS (n <= PREC(src)+1);
   170    EXP(src) = n;
   171    SIZ(src) = n;
   172    for (i = 0; i < SIZ(src); i++)
   173      PTR(src)[i] = i+100;
   174    mpf_set (trunc, src);
   175    mpf_set (ceil, src);
   176    mpf_set (floor, src);
   177    check_all (src, trunc, ceil, floor);
   178  
   179    /* full prec+1 limbs, 1 trimmed for integer */
   180    n = PREC(trunc)+1;
   181    ASSERT_ALWAYS (n <= PREC(src)+1);
   182    EXP(src) = n-1;
   183    SIZ(src) = n;
   184    for (i = 0; i < SIZ(src); i++)
   185      PTR(src)[i] = i+200;
   186    EXP(trunc) = n-1;
   187    SIZ(trunc) = n-1;
   188    for (i = 0; i < SIZ(trunc); i++)
   189      PTR(trunc)[i] = i+201;
   190    mpf_set (floor, trunc);
   191    mpf_add_ui (ceil, trunc, 1L);
   192    check_all (src, trunc, ceil, floor);
   193  
   194    /* prec+3 limbs, 2 trimmed for size */
   195    n = PREC(trunc)+3;
   196    ASSERT_ALWAYS (n <= PREC(src)+1);
   197    EXP(src) = n;
   198    SIZ(src) = n;
   199    for (i = 0; i < SIZ(src); i++)
   200      PTR(src)[i] = i+300;
   201    EXP(trunc) = n;
   202    SIZ(trunc) = n-2;
   203    for (i = 0; i < SIZ(trunc); i++)
   204      PTR(trunc)[i] = i+302;
   205    mpf_set (floor, trunc);
   206    mpf_set (ceil, trunc);
   207    PTR(ceil)[0]++;
   208    check_all (src, trunc, ceil, floor);
   209  
   210    /* prec+4 limbs, 2 trimmed for size, 1 trimmed for integer */
   211    n = PREC(trunc)+4;
   212    ASSERT_ALWAYS (n <= PREC(src)+1);
   213    EXP(src) = n-1;
   214    SIZ(src) = n;
   215    for (i = 0; i < SIZ(src); i++)
   216      PTR(src)[i] = i+400;
   217    EXP(trunc) = n-1;
   218    SIZ(trunc) = n-3;
   219    for (i = 0; i < SIZ(trunc); i++)
   220      PTR(trunc)[i] = i+403;
   221    mpf_set (floor, trunc);
   222    mpf_set (ceil, trunc);
   223    PTR(ceil)[0]++;
   224    check_all (src, trunc, ceil, floor);
   225  
   226    /* F.F, carry out of ceil */
   227    EXP(src) = 1;
   228    SIZ(src) = 2;
   229    PTR(src)[0] = GMP_NUMB_MAX;
   230    PTR(src)[1] = GMP_NUMB_MAX;
   231    EXP(trunc) = 1;
   232    SIZ(trunc) = 1;
   233    PTR(trunc)[0] = GMP_NUMB_MAX;
   234    mpf_set (floor, trunc);
   235    EXP(ceil) = 2;
   236    SIZ(ceil) = 1;
   237    PTR(ceil)[0] = 1;
   238    check_all (src, trunc, ceil, floor);
   239  
   240    /* FF.F, carry out of ceil */
   241    EXP(src) = 2;
   242    SIZ(src) = 3;
   243    PTR(src)[0] = GMP_NUMB_MAX;
   244    PTR(src)[1] = GMP_NUMB_MAX;
   245    PTR(src)[2] = GMP_NUMB_MAX;
   246    EXP(trunc) = 2;
   247    SIZ(trunc) = 2;
   248    PTR(trunc)[0] = GMP_NUMB_MAX;
   249    PTR(trunc)[1] = GMP_NUMB_MAX;
   250    mpf_set (floor, trunc);
   251    EXP(ceil) = 3;
   252    SIZ(ceil) = 1;
   253    PTR(ceil)[0] = 1;
   254    check_all (src, trunc, ceil, floor);
   255  
   256    mpf_clear (src);
   257    mpf_clear (trunc);
   258    mpf_clear (ceil);
   259    mpf_clear (floor);
   260  }
   261  
   262  int
   263  main (void)
   264  {
   265    tests_start ();
   266  
   267    check_various ();
   268  
   269    tests_end ();
   270    exit (0);
   271  }