Home | History | Annotate | Line # | Download | only in tests
      1      1.1  mrg /* Test file for mpfr_hypot.
      2      1.1  mrg 
      3  1.1.1.6  mrg Copyright 2001-2023 Free Software Foundation, Inc.
      4  1.1.1.3  mrg Contributed by the AriC and Caramba projects, INRIA.
      5      1.1  mrg 
      6      1.1  mrg This file is part of the GNU MPFR Library.
      7      1.1  mrg 
      8      1.1  mrg The GNU MPFR Library is free software; you can redistribute it and/or modify
      9      1.1  mrg it under the terms of the GNU Lesser General Public License as published by
     10      1.1  mrg the Free Software Foundation; either version 3 of the License, or (at your
     11      1.1  mrg option) any later version.
     12      1.1  mrg 
     13      1.1  mrg The GNU MPFR Library is distributed in the hope that it will be useful, but
     14      1.1  mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     15      1.1  mrg or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
     16      1.1  mrg License for more details.
     17      1.1  mrg 
     18      1.1  mrg You should have received a copy of the GNU Lesser General Public License
     19      1.1  mrg along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
     20  1.1.1.5  mrg https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
     21      1.1  mrg 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
     22      1.1  mrg 
     23      1.1  mrg #include "mpfr-test.h"
     24      1.1  mrg 
     25      1.1  mrg /* Non-zero when extended exponent range */
     26      1.1  mrg static int ext = 0;
     27      1.1  mrg 
     28      1.1  mrg static void
     29      1.1  mrg special (void)
     30      1.1  mrg {
     31      1.1  mrg   mpfr_t x, y, z;
     32      1.1  mrg 
     33      1.1  mrg   mpfr_init (x);
     34      1.1  mrg   mpfr_init (y);
     35      1.1  mrg   mpfr_init (z);
     36      1.1  mrg 
     37      1.1  mrg   mpfr_set_nan (x);
     38  1.1.1.3  mrg   mpfr_set_ui (y, 0, MPFR_RNDN);
     39  1.1.1.3  mrg   mpfr_hypot (z, x, x, MPFR_RNDN);
     40  1.1.1.3  mrg   MPFR_ASSERTN(mpfr_nan_p (z));
     41      1.1  mrg   mpfr_hypot (z, x, y, MPFR_RNDN);
     42      1.1  mrg   MPFR_ASSERTN(mpfr_nan_p (z));
     43  1.1.1.3  mrg   mpfr_hypot (z, y, x, MPFR_RNDN);
     44  1.1.1.3  mrg   MPFR_ASSERTN(mpfr_nan_p (z));
     45      1.1  mrg 
     46      1.1  mrg   mpfr_set_inf (x, 1);
     47      1.1  mrg   mpfr_set_inf (y, -1);
     48      1.1  mrg   mpfr_hypot (z, x, y, MPFR_RNDN);
     49      1.1  mrg   MPFR_ASSERTN(mpfr_inf_p (z) && mpfr_sgn (z) > 0);
     50      1.1  mrg 
     51      1.1  mrg   mpfr_set_inf (x, -1);
     52      1.1  mrg   mpfr_set_nan (y);
     53      1.1  mrg   mpfr_hypot (z, x, y, MPFR_RNDN);
     54      1.1  mrg   MPFR_ASSERTN(mpfr_inf_p (z) && mpfr_sgn (z) > 0);
     55      1.1  mrg 
     56      1.1  mrg   mpfr_set_nan (x);
     57      1.1  mrg   mpfr_set_inf (y, -1);
     58      1.1  mrg   mpfr_hypot (z, x, y, MPFR_RNDN);
     59      1.1  mrg   MPFR_ASSERTN(mpfr_inf_p (z) && mpfr_sgn (z) > 0);
     60      1.1  mrg 
     61      1.1  mrg   mpfr_clear (x);
     62      1.1  mrg   mpfr_clear (y);
     63      1.1  mrg   mpfr_clear (z);
     64      1.1  mrg }
     65      1.1  mrg 
     66      1.1  mrg static void
     67      1.1  mrg test_large (void)
     68      1.1  mrg {
     69      1.1  mrg   mpfr_t x, y, z, t;
     70      1.1  mrg 
     71      1.1  mrg   mpfr_init (x);
     72      1.1  mrg   mpfr_init (y);
     73      1.1  mrg   mpfr_init (z);
     74      1.1  mrg   mpfr_init (t);
     75      1.1  mrg 
     76      1.1  mrg   mpfr_set_ui (x, 21, MPFR_RNDN);
     77      1.1  mrg   mpfr_set_ui (y, 28, MPFR_RNDN);
     78      1.1  mrg   mpfr_set_ui (z, 35, MPFR_RNDN);
     79      1.1  mrg 
     80      1.1  mrg   mpfr_mul_2ui (x, x, MPFR_EMAX_DEFAULT-6, MPFR_RNDN);
     81      1.1  mrg   mpfr_mul_2ui (y, y, MPFR_EMAX_DEFAULT-6, MPFR_RNDN);
     82      1.1  mrg   mpfr_mul_2ui (z, z, MPFR_EMAX_DEFAULT-6, MPFR_RNDN);
     83      1.1  mrg 
     84      1.1  mrg   mpfr_hypot (t, x, y, MPFR_RNDN);
     85      1.1  mrg   if (mpfr_cmp (z, t))
     86      1.1  mrg     {
     87      1.1  mrg       printf ("Error in test_large: got\n");
     88      1.1  mrg       mpfr_out_str (stdout, 2, 0, t, MPFR_RNDN);
     89      1.1  mrg       printf ("\ninstead of\n");
     90      1.1  mrg       mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
     91      1.1  mrg       printf ("\n");
     92      1.1  mrg       exit (1);
     93      1.1  mrg     }
     94      1.1  mrg 
     95      1.1  mrg   mpfr_set_prec (x, 53);
     96      1.1  mrg   mpfr_set_prec (t, 53);
     97      1.1  mrg   mpfr_set_prec (y, 53);
     98      1.1  mrg   mpfr_set_str_binary (x, "0.11101100011110000011101000010101010011001101000001100E-1021");
     99      1.1  mrg   mpfr_set_str_binary (y, "0.11111001010011000001110110001101011100001000010010100E-1021");
    100      1.1  mrg   mpfr_hypot (t, x, y, MPFR_RNDN);
    101      1.1  mrg   mpfr_set_str_binary (z, "0.101010111100110111101110111110100110010011001010111E-1020");
    102      1.1  mrg   if (mpfr_cmp (z, t))
    103      1.1  mrg     {
    104      1.1  mrg       printf ("Error in test_large: got\n");
    105      1.1  mrg       mpfr_out_str (stdout, 2, 0, t, MPFR_RNDN);
    106      1.1  mrg       printf ("\ninstead of\n");
    107      1.1  mrg       mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
    108      1.1  mrg       printf ("\n");
    109      1.1  mrg       exit (1);
    110      1.1  mrg     }
    111      1.1  mrg 
    112      1.1  mrg   mpfr_set_prec (x, 240);
    113      1.1  mrg   mpfr_set_prec (y, 22);
    114      1.1  mrg   mpfr_set_prec (z, 2);
    115      1.1  mrg   mpfr_set_prec (t, 2);
    116      1.1  mrg   mpfr_set_str_binary (x, "0.100111011010010010110100000100000001100010011100110101101111111101011110111011011101010110100101111000111100010100110000100101011110111011100110100110100101110101101100011000001100000001111101110100100100011011011010110111100110010101000111e-7");
    117      1.1  mrg   mpfr_set_str_binary (y, "0.1111000010000011000111E-10");
    118      1.1  mrg   mpfr_hypot (t, x, y, MPFR_RNDN);
    119      1.1  mrg   mpfr_set_str_binary (z, "0.11E-7");
    120      1.1  mrg   if (mpfr_cmp (z, t))
    121      1.1  mrg     {
    122      1.1  mrg       printf ("Error in test_large: got\n");
    123      1.1  mrg       mpfr_out_str (stdout, 2, 0, t, MPFR_RNDN);
    124      1.1  mrg       printf ("\ninstead of\n");
    125      1.1  mrg       mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
    126      1.1  mrg       printf ("\n");
    127      1.1  mrg       exit (1);
    128      1.1  mrg     }
    129      1.1  mrg 
    130      1.1  mrg   mpfr_clear (x);
    131      1.1  mrg   mpfr_clear (y);
    132      1.1  mrg   mpfr_clear (z);
    133      1.1  mrg   mpfr_clear (t);
    134      1.1  mrg }
    135      1.1  mrg 
    136      1.1  mrg static void
    137      1.1  mrg test_small (void)
    138      1.1  mrg {
    139      1.1  mrg   mpfr_t x, y, z1, z2;
    140      1.1  mrg   int inex1, inex2;
    141      1.1  mrg   unsigned int flags;
    142      1.1  mrg 
    143      1.1  mrg   /* Test hypot(x,x) with x = 2^(emin-1). Result is x * sqrt(2). */
    144      1.1  mrg   mpfr_inits2 (8, x, y, z1, z2, (mpfr_ptr) 0);
    145      1.1  mrg   mpfr_set_si_2exp (x, 1, mpfr_get_emin () - 1, MPFR_RNDN);
    146      1.1  mrg   mpfr_set_si_2exp (y, 1, mpfr_get_emin () - 1, MPFR_RNDN);
    147      1.1  mrg   mpfr_set_ui (z1, 2, MPFR_RNDN);
    148      1.1  mrg   inex1 = mpfr_sqrt (z1, z1, MPFR_RNDN);
    149      1.1  mrg   inex2 = mpfr_mul (z1, z1, x, MPFR_RNDN);
    150      1.1  mrg   MPFR_ASSERTN (inex2 == 0);
    151      1.1  mrg   mpfr_clear_flags ();
    152      1.1  mrg   inex2 = mpfr_hypot (z2, x, y, MPFR_RNDN);
    153      1.1  mrg   flags = __gmpfr_flags;
    154      1.1  mrg   if (mpfr_cmp (z1, z2) != 0)
    155      1.1  mrg     {
    156      1.1  mrg       printf ("Error in test_small%s\nExpected ",
    157      1.1  mrg               ext ? ", extended exponent range" : "");
    158      1.1  mrg       mpfr_out_str (stdout, 2, 0, z1, MPFR_RNDN);
    159      1.1  mrg       printf ("\nGot      ");
    160      1.1  mrg       mpfr_out_str (stdout, 2, 0, z2, MPFR_RNDN);
    161      1.1  mrg       printf ("\n");
    162      1.1  mrg       exit (1);
    163      1.1  mrg     }
    164      1.1  mrg   if (! SAME_SIGN (inex1, inex2))
    165      1.1  mrg     {
    166      1.1  mrg       printf ("Bad ternary value in test_small%s\nExpected %d, got %d\n",
    167      1.1  mrg               ext ? ", extended exponent range" : "", inex1, inex2);
    168      1.1  mrg       exit (1);
    169      1.1  mrg     }
    170      1.1  mrg   if (flags != MPFR_FLAGS_INEXACT)
    171      1.1  mrg     {
    172      1.1  mrg       printf ("Bad flags in test_small%s\nExpected %u, got %u\n",
    173      1.1  mrg               ext ? ", extended exponent range" : "",
    174      1.1  mrg               (unsigned int) MPFR_FLAGS_INEXACT, flags);
    175      1.1  mrg       exit (1);
    176      1.1  mrg     }
    177      1.1  mrg   mpfr_clears (x, y, z1, z2, (mpfr_ptr) 0);
    178      1.1  mrg }
    179      1.1  mrg 
    180      1.1  mrg static void
    181      1.1  mrg test_large_small (void)
    182      1.1  mrg {
    183      1.1  mrg   mpfr_t x, y, z;
    184      1.1  mrg   int inexact, inex2, r;
    185      1.1  mrg 
    186      1.1  mrg   mpfr_init2 (x, 3);
    187      1.1  mrg   mpfr_init2 (y, 2);
    188      1.1  mrg   mpfr_init2 (z, 2);
    189      1.1  mrg 
    190      1.1  mrg   mpfr_set_ui_2exp (x, 1, mpfr_get_emax () / 2, MPFR_RNDN);
    191      1.1  mrg   mpfr_set_ui_2exp (y, 1, -1, MPFR_RNDN);
    192      1.1  mrg   inexact = mpfr_hypot (z, x, y, MPFR_RNDN);
    193      1.1  mrg   if (inexact >= 0 || mpfr_cmp (x, z))
    194      1.1  mrg     {
    195      1.1  mrg       printf ("Error 1 in test_large_small%s\n",
    196      1.1  mrg               ext ? ", extended exponent range" : "");
    197      1.1  mrg       exit (1);
    198      1.1  mrg     }
    199      1.1  mrg 
    200      1.1  mrg   mpfr_mul_ui (x, x, 5, MPFR_RNDN);
    201      1.1  mrg   inexact = mpfr_hypot (z, x, y, MPFR_RNDN);
    202      1.1  mrg   if (mpfr_cmp (x, z) >= 0)
    203      1.1  mrg     {
    204      1.1  mrg       printf ("Error 2 in test_large_small%s\n",
    205      1.1  mrg               ext ? ", extended exponent range" : "");
    206      1.1  mrg       printf ("x = ");
    207      1.1  mrg       mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
    208      1.1  mrg       printf ("\n");
    209      1.1  mrg       printf ("y = ");
    210      1.1  mrg       mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
    211      1.1  mrg       printf ("\n");
    212      1.1  mrg       printf ("z = ");
    213      1.1  mrg       mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
    214      1.1  mrg       printf (" (in precision 2) instead of\n    ");
    215      1.1  mrg       mpfr_out_str (stdout, 2, 2, x, MPFR_RNDU);
    216      1.1  mrg       printf ("\n");
    217      1.1  mrg       exit (1);
    218      1.1  mrg     }
    219      1.1  mrg 
    220      1.1  mrg   RND_LOOP(r)
    221      1.1  mrg     {
    222      1.1  mrg       mpfr_set_ui_2exp (x, 1, mpfr_get_emax () - 1, MPFR_RNDN);
    223      1.1  mrg       mpfr_set_ui_2exp (y, 1, mpfr_get_emin (), MPFR_RNDN);
    224      1.1  mrg       inexact = mpfr_hypot (z, x, y, (mpfr_rnd_t) r);
    225      1.1  mrg       inex2 = mpfr_add_ui (y, x, 1, (mpfr_rnd_t) r);
    226      1.1  mrg       if (! mpfr_equal_p (y, z) || ! SAME_SIGN (inexact, inex2))
    227      1.1  mrg         {
    228      1.1  mrg           printf ("Error 3 in test_large_small, %s%s\n",
    229      1.1  mrg                   mpfr_print_rnd_mode ((mpfr_rnd_t) r),
    230      1.1  mrg                   ext ? ", extended exponent range" : "");
    231      1.1  mrg           printf ("Expected ");
    232      1.1  mrg           mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
    233      1.1  mrg           printf (", inex = %d\n", inex2);
    234      1.1  mrg           printf ("Got      ");
    235      1.1  mrg           mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
    236      1.1  mrg           printf (", inex = %d\n", inexact);
    237      1.1  mrg           exit (1);
    238      1.1  mrg         }
    239      1.1  mrg     }
    240      1.1  mrg 
    241      1.1  mrg   mpfr_clear (x);
    242      1.1  mrg   mpfr_clear (y);
    243      1.1  mrg   mpfr_clear (z);
    244      1.1  mrg }
    245      1.1  mrg 
    246      1.1  mrg static void
    247      1.1  mrg check_overflow (void)
    248      1.1  mrg {
    249      1.1  mrg   mpfr_t x, y;
    250      1.1  mrg   int inex, r;
    251      1.1  mrg 
    252      1.1  mrg   mpfr_inits2 (8, x, y, (mpfr_ptr) 0);
    253      1.1  mrg   mpfr_set_ui (x, 1, MPFR_RNDN);
    254      1.1  mrg   mpfr_setmax (x, mpfr_get_emax ());
    255      1.1  mrg 
    256      1.1  mrg   RND_LOOP(r)
    257      1.1  mrg     {
    258      1.1  mrg       mpfr_clear_overflow ();
    259      1.1  mrg       inex = mpfr_hypot (y, x, x, (mpfr_rnd_t) r);
    260      1.1  mrg       if (!mpfr_overflow_p ())
    261      1.1  mrg         {
    262      1.1  mrg           printf ("No overflow in check_overflow for %s%s\n",
    263      1.1  mrg                   mpfr_print_rnd_mode ((mpfr_rnd_t) r),
    264      1.1  mrg                   ext ? ", extended exponent range" : "");
    265      1.1  mrg           exit (1);
    266      1.1  mrg         }
    267      1.1  mrg       MPFR_ASSERTN (MPFR_IS_POS (y));
    268      1.1  mrg       if (r == MPFR_RNDZ || r == MPFR_RNDD)
    269      1.1  mrg         {
    270      1.1  mrg           MPFR_ASSERTN (inex < 0);
    271      1.1  mrg           MPFR_ASSERTN (!mpfr_inf_p (y));
    272      1.1  mrg           mpfr_nexttoinf (y);
    273      1.1  mrg         }
    274      1.1  mrg       else
    275      1.1  mrg         {
    276      1.1  mrg           MPFR_ASSERTN (inex > 0);
    277      1.1  mrg         }
    278      1.1  mrg       MPFR_ASSERTN (mpfr_inf_p (y));
    279      1.1  mrg     }
    280      1.1  mrg 
    281      1.1  mrg   mpfr_clears (x, y, (mpfr_ptr) 0);
    282      1.1  mrg }
    283      1.1  mrg 
    284      1.1  mrg #define TWO_ARGS
    285      1.1  mrg #define TEST_FUNCTION mpfr_hypot
    286      1.1  mrg #include "tgeneric.c"
    287      1.1  mrg 
    288      1.1  mrg static void
    289      1.1  mrg alltst (void)
    290      1.1  mrg {
    291      1.1  mrg   mpfr_exp_t emin, emax;
    292      1.1  mrg 
    293      1.1  mrg   ext = 0;
    294      1.1  mrg   test_small ();
    295      1.1  mrg   test_large_small ();
    296      1.1  mrg   check_overflow ();
    297      1.1  mrg 
    298      1.1  mrg   emin = mpfr_get_emin ();
    299      1.1  mrg   emax = mpfr_get_emax ();
    300      1.1  mrg   set_emin (MPFR_EMIN_MIN);
    301      1.1  mrg   set_emax (MPFR_EMAX_MAX);
    302      1.1  mrg   if (mpfr_get_emin () != emin || mpfr_get_emax () != emax)
    303      1.1  mrg     {
    304      1.1  mrg       ext = 1;
    305      1.1  mrg       test_small ();
    306      1.1  mrg       test_large_small ();
    307      1.1  mrg       check_overflow ();
    308      1.1  mrg       set_emin (emin);
    309      1.1  mrg       set_emax (emax);
    310      1.1  mrg     }
    311      1.1  mrg }
    312      1.1  mrg 
    313  1.1.1.4  mrg /* Test failing with GMP_CHECK_RANDOMIZE=1513841234 (overflow flag not set).
    314  1.1.1.4  mrg    The bug was in fact in mpfr_nexttoinf which didn't set the overflow flag. */
    315  1.1.1.4  mrg static void
    316  1.1.1.4  mrg bug20171221 (void)
    317  1.1.1.4  mrg {
    318  1.1.1.4  mrg   mpfr_t x, u, y;
    319  1.1.1.4  mrg   int inex;
    320  1.1.1.4  mrg   mpfr_exp_t emax;
    321  1.1.1.4  mrg 
    322  1.1.1.4  mrg   mpfr_init2 (x, 12);
    323  1.1.1.4  mrg   mpfr_init2 (u, 12);
    324  1.1.1.4  mrg   mpfr_init2 (y, 11);
    325  1.1.1.4  mrg   mpfr_set_str_binary (x, "0.111111111110E0");
    326  1.1.1.4  mrg   mpfr_set_str_binary (u, "0.111011110100E-177");
    327  1.1.1.4  mrg   emax = mpfr_get_emax ();
    328  1.1.1.6  mrg   set_emax (0);
    329  1.1.1.4  mrg   mpfr_clear_flags ();
    330  1.1.1.4  mrg   inex = mpfr_hypot (y, x, u, MPFR_RNDU);
    331  1.1.1.4  mrg   MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) > 0);
    332  1.1.1.4  mrg   MPFR_ASSERTN(inex > 0);
    333  1.1.1.4  mrg   MPFR_ASSERTN(mpfr_inexflag_p ());
    334  1.1.1.4  mrg   MPFR_ASSERTN(mpfr_overflow_p ());
    335  1.1.1.6  mrg   set_emax (emax);
    336  1.1.1.6  mrg   mpfr_clear (x);
    337  1.1.1.6  mrg   mpfr_clear (u);
    338  1.1.1.6  mrg   mpfr_clear (y);
    339  1.1.1.6  mrg }
    340  1.1.1.6  mrg 
    341  1.1.1.6  mrg /* check overflow for x=0xf.ffffffffffff8p+1020 and u=0xf.fffffp+124
    342  1.1.1.6  mrg    with rounding upwards and emax=1024 (as in binary64) */
    343  1.1.1.6  mrg static void
    344  1.1.1.6  mrg test_overflow (void)
    345  1.1.1.6  mrg {
    346  1.1.1.6  mrg   mpfr_t x, u, y;
    347  1.1.1.6  mrg   int inex;
    348  1.1.1.6  mrg   mpfr_exp_t emax;
    349  1.1.1.6  mrg 
    350  1.1.1.6  mrg   mpfr_init2 (x, 53);
    351  1.1.1.6  mrg   mpfr_init2 (u, 53);
    352  1.1.1.6  mrg   mpfr_init2 (y, 53);
    353  1.1.1.6  mrg   mpfr_set_str (x, "0xf.ffffffffffff8p+1020", 16, MPFR_RNDN);
    354  1.1.1.6  mrg   mpfr_set_str (u, "0xf.fffffp+124", 16, MPFR_RNDN);
    355  1.1.1.6  mrg   emax = mpfr_get_emax ();
    356  1.1.1.6  mrg   set_emax (1024);
    357  1.1.1.6  mrg   mpfr_clear_flags ();
    358  1.1.1.6  mrg   inex = mpfr_hypot (y, x, u, MPFR_RNDU);
    359  1.1.1.6  mrg   MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) > 0);
    360  1.1.1.6  mrg   MPFR_ASSERTN(inex > 0);
    361  1.1.1.6  mrg   MPFR_ASSERTN(mpfr_inexflag_p ());
    362  1.1.1.6  mrg   MPFR_ASSERTN(mpfr_overflow_p ());
    363  1.1.1.6  mrg   set_emax (emax);
    364  1.1.1.4  mrg   mpfr_clear (x);
    365  1.1.1.4  mrg   mpfr_clear (u);
    366  1.1.1.4  mrg   mpfr_clear (y);
    367  1.1.1.4  mrg }
    368  1.1.1.4  mrg 
    369      1.1  mrg int
    370      1.1  mrg main (int argc, char *argv[])
    371      1.1  mrg {
    372      1.1  mrg   tests_start_mpfr ();
    373      1.1  mrg 
    374  1.1.1.4  mrg   bug20171221 ();
    375      1.1  mrg   special ();
    376      1.1  mrg 
    377      1.1  mrg   test_large ();
    378      1.1  mrg   alltst ();
    379  1.1.1.6  mrg   test_overflow ();
    380      1.1  mrg 
    381  1.1.1.4  mrg   test_generic (MPFR_PREC_MIN, 100, 10);
    382      1.1  mrg 
    383      1.1  mrg   tests_end_mpfr ();
    384      1.1  mrg   return 0;
    385      1.1  mrg }
    386