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