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

     1  /* Test mpf_ui_div.
     2  
     3  Copyright 2004 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_one (const char *desc, mpf_ptr got, unsigned long u, mpf_srcptr v)
    29  {
    30    mpf_t      uf;
    31    mp_limb_t  ulimbs[2];
    32    mp_size_t  usize;
    33  
    34    ulimbs[0] = u & GMP_NUMB_MASK;
    35    usize = (u != 0);
    36  #if BITS_PER_ULONG > GMP_NUMB_BITS
    37    u >>= GMP_NUMB_BITS;
    38    ulimbs[1] = u;
    39    usize += (u != 0);
    40  #endif
    41    PTR(uf) = ulimbs;
    42    SIZ(uf) = usize;
    43    EXP(uf) = usize;
    44  
    45    if (! refmpf_validate_division ("mpf_ui_div", got, uf, v))
    46      {
    47        mp_trace_base = -16;
    48        printf    ("  u 0x%lX  (%lu)\n", u, u);
    49        mpf_trace ("  v", v);
    50        printf    ("  %s\n", desc);
    51        abort ();
    52      }
    53  }
    54  
    55  void
    56  check_rand (void)
    57  {
    58    unsigned long  min_prec = __GMPF_BITS_TO_PREC (1);
    59    gmp_randstate_ptr  rands = RANDS;
    60    unsigned long  prec, u;
    61    mpf_t  got, v;
    62    int    i;
    63  
    64    mpf_init (got);
    65    mpf_init (v);
    66  
    67    for (i = 0; i < 200; i++)
    68      {
    69        /* got precision */
    70        prec = min_prec + gmp_urandomm_ui (rands, 15L);
    71        refmpf_set_prec_limbs (got, prec);
    72  
    73        /* u */
    74        prec = gmp_urandomm_ui (rands, BITS_PER_ULONG+1);
    75        u = gmp_urandomb_ui (rands, prec);
    76  
    77        /* v precision */
    78        prec = min_prec + gmp_urandomm_ui (rands, 15L);
    79        refmpf_set_prec_limbs (v, prec);
    80  
    81        /* v, non-zero */
    82        do {
    83          mpf_random2 (v, PREC(v), (mp_exp_t) 20);
    84        } while (SIZ(v) == 0);
    85  
    86        /* v possibly negative */
    87        if (gmp_urandomb_ui (rands, 1L))
    88          mpf_neg (v, v);
    89  
    90        if ((i % 2) == 0)
    91          {
    92            /* src != dst */
    93            mpf_ui_div (got, u, v);
    94            check_one ("separate", got, u, v);
    95          }
    96        else
    97          {
    98            /* src == dst */
    99            prec = refmpf_set_overlap (got, v);
   100            mpf_ui_div (got, u, got);
   101            check_one ("overlap src==dst", got, u, v);
   102  
   103            mpf_set_prec_raw (got, prec);
   104          }
   105      }
   106  
   107    mpf_clear (got);
   108    mpf_clear (v);
   109  }
   110  
   111  void
   112  check_various (void)
   113  {
   114    mpf_t got, v;
   115  
   116    mpf_init (got);
   117    mpf_init (v);
   118  
   119    /* 100/4 == 25 */
   120    mpf_set_prec (got, 20L);
   121    mpf_set_ui (v, 4L);
   122    mpf_ui_div (got, 100L, v);
   123    MPF_CHECK_FORMAT (got);
   124    ASSERT_ALWAYS (mpf_cmp_ui (got, 25L) == 0);
   125  
   126    {
   127      /* 1/(2^n+1), a case where truncating the divisor would be wrong */
   128      unsigned long  u = 1L;
   129      mpf_set_prec (got, 500L);
   130      mpf_set_prec (v, 900L);
   131      mpf_set_ui (v, 1L);
   132      mpf_mul_2exp (v, v, 800L);
   133      mpf_add_ui (v, v, 1L);
   134      mpf_ui_div (got, u, v);
   135      check_one ("1/2^n+1, separate", got, u, v);
   136    }
   137  
   138    mpf_clear (got);
   139    mpf_clear (v);
   140  }
   141  
   142  int
   143  main (void)
   144  {
   145    tests_start ();
   146  
   147    check_various ();
   148    check_rand ();
   149  
   150    tests_end ();
   151    exit (0);
   152  }