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

     1  /* Test mpf_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, mpf_srcptr u, mpf_srcptr v)
    29  {
    30    if (! refmpf_validate_division ("mpf_div", got, u, v))
    31      {
    32        mp_trace_base = -16;
    33        mpf_trace ("  u", u);
    34        mpf_trace ("  v", v);
    35        printf    ("  %s\n", desc);
    36        abort ();
    37      }
    38  }
    39  
    40  void
    41  check_rand (void)
    42  {
    43    unsigned long  min_prec = __GMPF_BITS_TO_PREC (1);
    44    gmp_randstate_ptr  rands = RANDS;
    45    unsigned long  prec;
    46    mpf_t  got, u, v;
    47    int    i;
    48  
    49    mpf_init (got);
    50    mpf_init (u);
    51    mpf_init (v);
    52  
    53    /* separate */
    54    for (i = 0; i < 100; i++)
    55      {
    56        /* got precision */
    57        prec = min_prec + gmp_urandomm_ui (rands, 15L);
    58        refmpf_set_prec_limbs (got, prec);
    59  
    60        /* u */
    61        prec = min_prec + gmp_urandomm_ui (rands, 15L);
    62        refmpf_set_prec_limbs (u, prec);
    63        do {
    64          mpf_random2 (u, PREC(u), (mp_exp_t) 20);
    65        } while (SIZ(u) == 0);
    66        if (gmp_urandomb_ui (rands, 1L))
    67          mpf_neg (u, u);
    68  
    69        /* v */
    70        prec = min_prec + gmp_urandomm_ui (rands, 15L);
    71        refmpf_set_prec_limbs (v, prec);
    72        do {
    73          mpf_random2 (v, PREC(v), (mp_exp_t) 20);
    74        } while (SIZ(v) == 0);
    75        if (gmp_urandomb_ui (rands, 1L))
    76          mpf_neg (v, v);
    77  
    78        switch (i % 3) {
    79        case 0:
    80          mpf_div (got, u, v);
    81          check_one ("separate", got, u, v);
    82          break;
    83        case 1:
    84          prec = refmpf_set_overlap (got, u);
    85          mpf_div (got, got, v);
    86          check_one ("dst == u", got, u, v);
    87          mpf_set_prec_raw (got, prec);
    88          break;
    89        case 2:
    90          prec = refmpf_set_overlap (got, v);
    91          mpf_div (got, u, got);
    92          check_one ("dst == v", got, u, v);
    93          mpf_set_prec_raw (got, prec);
    94          break;
    95        }
    96      }
    97  
    98    mpf_clear (got);
    99    mpf_clear (u);
   100    mpf_clear (v);
   101  }
   102  
   103  /* Exercise calls mpf(x,x,x) */
   104  void
   105  check_reuse_three (void)
   106  {
   107    unsigned long  min_prec = __GMPF_BITS_TO_PREC (1);
   108    gmp_randstate_ptr  rands = RANDS;
   109    unsigned long  result_prec, input_prec, set_prec;
   110    mpf_t  got;
   111    int    i;
   112  
   113    mpf_init (got);
   114  
   115    for (i = 0; i < 8; i++)
   116      {
   117        result_prec = min_prec + gmp_urandomm_ui (rands, 15L);
   118        input_prec = min_prec + gmp_urandomm_ui (rands, 15L);
   119  
   120        set_prec = MAX (result_prec, input_prec);
   121        refmpf_set_prec_limbs (got, set_prec);
   122  
   123        /* input, non-zero, possibly negative */
   124        PREC(got) = input_prec;
   125        do {
   126          mpf_random2 (got, input_prec, (mp_exp_t) 20);
   127        } while (SIZ(got) == 0);
   128        if (gmp_urandomb_ui (rands, 1L))
   129          mpf_neg (got, got);
   130  
   131        PREC(got) = result_prec;
   132  
   133        mpf_div (got, got, got);
   134  
   135        /* expect exactly 1.0 always */
   136        ASSERT_ALWAYS (mpf_cmp_ui (got, 1L) == 0);
   137  
   138        PREC(got) = set_prec;
   139      }
   140  
   141    mpf_clear (got);
   142  }
   143  
   144  void
   145  check_various (void)
   146  {
   147    mpf_t got, u, v;
   148  
   149    mpf_init (got);
   150    mpf_init (u);
   151    mpf_init (v);
   152  
   153    /* 100/4 == 25 */
   154    mpf_set_prec (got, 20L);
   155    mpf_set_ui (u, 100L);
   156    mpf_set_ui (v, 4L);
   157    mpf_div (got, u, v);
   158    MPF_CHECK_FORMAT (got);
   159    ASSERT_ALWAYS (mpf_cmp_ui (got, 25L) == 0);
   160  
   161    /* 1/(2^n+1), a case where truncating the divisor would be wrong */
   162    mpf_set_prec (got, 500L);
   163    mpf_set_prec (v, 900L);
   164    mpf_set_ui (v, 1L);
   165    mpf_mul_2exp (v, v, 800L);
   166    mpf_add_ui (v, v, 1L);
   167    mpf_div (got, u, v);
   168    check_one ("1/2^n+1, separate", got, u, v);
   169  
   170    mpf_clear (got);
   171    mpf_clear (u);
   172    mpf_clear (v);
   173  }
   174  
   175  int
   176  main (void)
   177  {
   178    tests_start ();
   179  
   180    check_various ();
   181    check_rand ();
   182    check_reuse_three ();
   183  
   184    tests_end ();
   185    exit (0);
   186  }