Home | History | Annotate | Line # | Download | only in tests
tsqrt.c revision 1.1
      1  1.1  mrg /* Test file for mpfr_sqrt.
      2  1.1  mrg 
      3  1.1  mrg Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
      4  1.1  mrg Contributed by the Arenaire and Cacao 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  mrg http://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 <stdio.h>
     24  1.1  mrg #include <stdlib.h>
     25  1.1  mrg 
     26  1.1  mrg #include "mpfr-test.h"
     27  1.1  mrg 
     28  1.1  mrg #ifdef CHECK_EXTERNAL
     29  1.1  mrg static int
     30  1.1  mrg test_sqrt (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
     31  1.1  mrg {
     32  1.1  mrg   int res;
     33  1.1  mrg   int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b);
     34  1.1  mrg   if (ok)
     35  1.1  mrg     {
     36  1.1  mrg       mpfr_print_raw (b);
     37  1.1  mrg     }
     38  1.1  mrg   res = mpfr_sqrt (a, b, rnd_mode);
     39  1.1  mrg   if (ok)
     40  1.1  mrg     {
     41  1.1  mrg       printf (" ");
     42  1.1  mrg       mpfr_print_raw (a);
     43  1.1  mrg       printf ("\n");
     44  1.1  mrg     }
     45  1.1  mrg   return res;
     46  1.1  mrg }
     47  1.1  mrg #else
     48  1.1  mrg #define test_sqrt mpfr_sqrt
     49  1.1  mrg #endif
     50  1.1  mrg 
     51  1.1  mrg static void
     52  1.1  mrg check3 (const char *as, mpfr_rnd_t rnd_mode, const char *qs)
     53  1.1  mrg {
     54  1.1  mrg   mpfr_t q;
     55  1.1  mrg 
     56  1.1  mrg   mpfr_init2 (q, 53);
     57  1.1  mrg   mpfr_set_str1 (q, as);
     58  1.1  mrg   test_sqrt (q, q, rnd_mode);
     59  1.1  mrg   if (mpfr_cmp_str1 (q, qs) )
     60  1.1  mrg     {
     61  1.1  mrg       printf ("mpfr_sqrt failed for a=%s, rnd_mode=%s\n",
     62  1.1  mrg               as, mpfr_print_rnd_mode (rnd_mode));
     63  1.1  mrg       printf ("expected sqrt is %s, got ",qs);
     64  1.1  mrg       mpfr_out_str (stdout, 10, 0, q, MPFR_RNDN);
     65  1.1  mrg       putchar ('\n');
     66  1.1  mrg       exit (1);
     67  1.1  mrg     }
     68  1.1  mrg   mpfr_clear (q);
     69  1.1  mrg }
     70  1.1  mrg 
     71  1.1  mrg static void
     72  1.1  mrg check4 (const char *as, mpfr_rnd_t rnd_mode, const char *Qs)
     73  1.1  mrg {
     74  1.1  mrg   mpfr_t q;
     75  1.1  mrg 
     76  1.1  mrg   mpfr_init2 (q, 53);
     77  1.1  mrg   mpfr_set_str1 (q, as);
     78  1.1  mrg   test_sqrt (q, q, rnd_mode);
     79  1.1  mrg   if (mpfr_cmp_str (q, Qs, 16, MPFR_RNDN))
     80  1.1  mrg     {
     81  1.1  mrg       printf ("mpfr_sqrt failed for a=%s, rnd_mode=%s\n",
     82  1.1  mrg               as, mpfr_print_rnd_mode(rnd_mode));
     83  1.1  mrg       printf ("expected ");
     84  1.1  mrg       mpfr_out_str (stdout, 16, 0, q, MPFR_RNDN);
     85  1.1  mrg       printf ("\ngot      %s\n", Qs);
     86  1.1  mrg       mpfr_clear (q);
     87  1.1  mrg       exit (1);
     88  1.1  mrg     }
     89  1.1  mrg   mpfr_clear (q);
     90  1.1  mrg }
     91  1.1  mrg 
     92  1.1  mrg static void
     93  1.1  mrg check24 (const char *as, mpfr_rnd_t rnd_mode, const char *qs)
     94  1.1  mrg {
     95  1.1  mrg   mpfr_t q;
     96  1.1  mrg 
     97  1.1  mrg   mpfr_init2 (q, 24);
     98  1.1  mrg   mpfr_set_str1 (q, as);
     99  1.1  mrg   test_sqrt (q, q, rnd_mode);
    100  1.1  mrg   if (mpfr_cmp_str1 (q, qs))
    101  1.1  mrg     {
    102  1.1  mrg       printf ("mpfr_sqrt failed for a=%s, prec=24, rnd_mode=%s\n",
    103  1.1  mrg               as, mpfr_print_rnd_mode(rnd_mode));
    104  1.1  mrg       printf ("expected sqrt is %s, got ",qs);
    105  1.1  mrg       mpfr_out_str (stdout, 10, 0, q, MPFR_RNDN);
    106  1.1  mrg       printf ("\n");
    107  1.1  mrg       exit (1);
    108  1.1  mrg     }
    109  1.1  mrg   mpfr_clear (q);
    110  1.1  mrg }
    111  1.1  mrg 
    112  1.1  mrg static void
    113  1.1  mrg check_diverse (const char *as, mpfr_prec_t p, const char *qs)
    114  1.1  mrg {
    115  1.1  mrg   mpfr_t q;
    116  1.1  mrg 
    117  1.1  mrg   mpfr_init2 (q, p);
    118  1.1  mrg   mpfr_set_str1 (q, as);
    119  1.1  mrg   test_sqrt (q, q, MPFR_RNDN);
    120  1.1  mrg   if (mpfr_cmp_str1 (q, qs))
    121  1.1  mrg     {
    122  1.1  mrg       printf ("mpfr_sqrt failed for a=%s, prec=%lu, rnd_mode=%s\n",
    123  1.1  mrg               as, p, mpfr_print_rnd_mode (MPFR_RNDN));
    124  1.1  mrg       printf ("expected sqrt is %s, got ", qs);
    125  1.1  mrg       mpfr_out_str (stdout, 10, 0, q, MPFR_RNDN);
    126  1.1  mrg       printf ("\n");
    127  1.1  mrg       exit (1);
    128  1.1  mrg     }
    129  1.1  mrg   mpfr_clear (q);
    130  1.1  mrg }
    131  1.1  mrg 
    132  1.1  mrg /* the following examples come from the paper "Number-theoretic Test
    133  1.1  mrg    Generation for Directed Rounding" from Michael Parks, Table 3 */
    134  1.1  mrg static void
    135  1.1  mrg check_float (void)
    136  1.1  mrg {
    137  1.1  mrg   check24("70368760954880.0", MPFR_RNDN, "8.388609e6");
    138  1.1  mrg   check24("281474943156224.0", MPFR_RNDN, "1.6777215e7");
    139  1.1  mrg   check24("70368777732096.0", MPFR_RNDN, "8.388610e6");
    140  1.1  mrg   check24("281474909601792.0", MPFR_RNDN, "1.6777214e7");
    141  1.1  mrg   check24("100216216748032.0", MPFR_RNDN, "1.0010805e7");
    142  1.1  mrg   check24("120137273311232.0", MPFR_RNDN, "1.0960715e7");
    143  1.1  mrg   check24("229674600890368.0", MPFR_RNDN, "1.5155019e7");
    144  1.1  mrg   check24("70368794509312.0", MPFR_RNDN, "8.388611e6");
    145  1.1  mrg   check24("281474876047360.0", MPFR_RNDN, "1.6777213e7");
    146  1.1  mrg   check24("91214552498176.0", MPFR_RNDN, "9.550631e6");
    147  1.1  mrg 
    148  1.1  mrg   check24("70368760954880.0", MPFR_RNDZ, "8.388608e6");
    149  1.1  mrg   check24("281474943156224.0", MPFR_RNDZ, "1.6777214e7");
    150  1.1  mrg   check24("70368777732096.0", MPFR_RNDZ, "8.388609e6");
    151  1.1  mrg   check24("281474909601792.0", MPFR_RNDZ, "1.6777213e7");
    152  1.1  mrg   check24("100216216748032.0", MPFR_RNDZ, "1.0010805e7");
    153  1.1  mrg   check24("120137273311232.0", MPFR_RNDZ, "1.0960715e7");
    154  1.1  mrg   check24("229674600890368.0", MPFR_RNDZ, "1.5155019e7");
    155  1.1  mrg   check24("70368794509312.0", MPFR_RNDZ, "8.38861e6");
    156  1.1  mrg   check24("281474876047360.0", MPFR_RNDZ, "1.6777212e7");
    157  1.1  mrg   check24("91214552498176.0", MPFR_RNDZ, "9.550631e6");
    158  1.1  mrg 
    159  1.1  mrg   check24("70368760954880.0", MPFR_RNDU, "8.388609e6");
    160  1.1  mrg   check24("281474943156224.0",MPFR_RNDU, "1.6777215e7");
    161  1.1  mrg   check24("70368777732096.0", MPFR_RNDU, "8.388610e6");
    162  1.1  mrg   check24("281474909601792.0", MPFR_RNDU, "1.6777214e7");
    163  1.1  mrg   check24("100216216748032.0", MPFR_RNDU, "1.0010806e7");
    164  1.1  mrg   check24("120137273311232.0", MPFR_RNDU, "1.0960716e7");
    165  1.1  mrg   check24("229674600890368.0", MPFR_RNDU, "1.515502e7");
    166  1.1  mrg   check24("70368794509312.0", MPFR_RNDU, "8.388611e6");
    167  1.1  mrg   check24("281474876047360.0", MPFR_RNDU, "1.6777213e7");
    168  1.1  mrg   check24("91214552498176.0", MPFR_RNDU, "9.550632e6");
    169  1.1  mrg 
    170  1.1  mrg   check24("70368760954880.0", MPFR_RNDD, "8.388608e6");
    171  1.1  mrg   check24("281474943156224.0", MPFR_RNDD, "1.6777214e7");
    172  1.1  mrg   check24("70368777732096.0", MPFR_RNDD, "8.388609e6");
    173  1.1  mrg   check24("281474909601792.0", MPFR_RNDD, "1.6777213e7");
    174  1.1  mrg   check24("100216216748032.0", MPFR_RNDD, "1.0010805e7");
    175  1.1  mrg   check24("120137273311232.0", MPFR_RNDD, "1.0960715e7");
    176  1.1  mrg   check24("229674600890368.0", MPFR_RNDD, "1.5155019e7");
    177  1.1  mrg   check24("70368794509312.0", MPFR_RNDD, "8.38861e6");
    178  1.1  mrg   check24("281474876047360.0", MPFR_RNDD, "1.6777212e7");
    179  1.1  mrg   check24("91214552498176.0", MPFR_RNDD, "9.550631e6");
    180  1.1  mrg 
    181  1.1  mrg   /* check that rounding away is just rounding toward plus infinity */
    182  1.1  mrg   check24("91214552498176.0", MPFR_RNDA, "9.550632e6");
    183  1.1  mrg }
    184  1.1  mrg 
    185  1.1  mrg static void
    186  1.1  mrg special (void)
    187  1.1  mrg {
    188  1.1  mrg   mpfr_t x, y, z;
    189  1.1  mrg   int inexact;
    190  1.1  mrg   mpfr_prec_t p;
    191  1.1  mrg 
    192  1.1  mrg   mpfr_init (x);
    193  1.1  mrg   mpfr_init (y);
    194  1.1  mrg   mpfr_init (z);
    195  1.1  mrg 
    196  1.1  mrg   mpfr_set_prec (x, 64);
    197  1.1  mrg   mpfr_set_str_binary (x, "1010000010100011011001010101010010001100001101011101110001011001E-1");
    198  1.1  mrg   mpfr_set_prec (y, 32);
    199  1.1  mrg   test_sqrt (y, x, MPFR_RNDN);
    200  1.1  mrg   if (mpfr_cmp_ui (y, 2405743844UL))
    201  1.1  mrg     {
    202  1.1  mrg       printf ("Error for n^2+n+1/2 with n=2405743843\n");
    203  1.1  mrg       exit (1);
    204  1.1  mrg     }
    205  1.1  mrg 
    206  1.1  mrg   mpfr_set_prec (x, 65);
    207  1.1  mrg   mpfr_set_str_binary (x, "10100000101000110110010101010100100011000011010111011100010110001E-2");
    208  1.1  mrg   mpfr_set_prec (y, 32);
    209  1.1  mrg   test_sqrt (y, x, MPFR_RNDN);
    210  1.1  mrg   if (mpfr_cmp_ui (y, 2405743844UL))
    211  1.1  mrg     {
    212  1.1  mrg       printf ("Error for n^2+n+1/4 with n=2405743843\n");
    213  1.1  mrg       mpfr_dump (y);
    214  1.1  mrg       exit (1);
    215  1.1  mrg     }
    216  1.1  mrg 
    217  1.1  mrg   mpfr_set_prec (x, 66);
    218  1.1  mrg   mpfr_set_str_binary (x, "101000001010001101100101010101001000110000110101110111000101100011E-3");
    219  1.1  mrg   mpfr_set_prec (y, 32);
    220  1.1  mrg   test_sqrt (y, x, MPFR_RNDN);
    221  1.1  mrg   if (mpfr_cmp_ui (y, 2405743844UL))
    222  1.1  mrg     {
    223  1.1  mrg       printf ("Error for n^2+n+1/4+1/8 with n=2405743843\n");
    224  1.1  mrg       mpfr_dump (y);
    225  1.1  mrg       exit (1);
    226  1.1  mrg     }
    227  1.1  mrg 
    228  1.1  mrg   mpfr_set_prec (x, 66);
    229  1.1  mrg   mpfr_set_str_binary (x, "101000001010001101100101010101001000110000110101110111000101100001E-3");
    230  1.1  mrg   mpfr_set_prec (y, 32);
    231  1.1  mrg   test_sqrt (y, x, MPFR_RNDN);
    232  1.1  mrg   if (mpfr_cmp_ui (y, 2405743843UL))
    233  1.1  mrg     {
    234  1.1  mrg       printf ("Error for n^2+n+1/8 with n=2405743843\n");
    235  1.1  mrg       mpfr_dump (y);
    236  1.1  mrg       exit (1);
    237  1.1  mrg     }
    238  1.1  mrg 
    239  1.1  mrg   mpfr_set_prec (x, 27);
    240  1.1  mrg   mpfr_set_str_binary (x, "0.110100111010101000010001011");
    241  1.1  mrg   if ((inexact = test_sqrt (x, x, MPFR_RNDZ)) >= 0)
    242  1.1  mrg     {
    243  1.1  mrg       printf ("Wrong inexact flag: expected -1, got %d\n", inexact);
    244  1.1  mrg       exit (1);
    245  1.1  mrg     }
    246  1.1  mrg 
    247  1.1  mrg   mpfr_set_prec (x, 2);
    248  1.1  mrg   for (p=2; p<1000; p++)
    249  1.1  mrg     {
    250  1.1  mrg       mpfr_set_prec (z, p);
    251  1.1  mrg       mpfr_set_ui (z, 1, MPFR_RNDN);
    252  1.1  mrg       mpfr_nexttoinf (z);
    253  1.1  mrg       test_sqrt (x, z, MPFR_RNDU);
    254  1.1  mrg       if (mpfr_cmp_ui_2exp(x, 3, -1))
    255  1.1  mrg         {
    256  1.1  mrg           printf ("Error: sqrt(1+ulp(1), up) should give 1.5 (prec=%u)\n",
    257  1.1  mrg                   (unsigned int) p);
    258  1.1  mrg           printf ("got "); mpfr_print_binary (x); puts ("");
    259  1.1  mrg           exit (1);
    260  1.1  mrg         }
    261  1.1  mrg     }
    262  1.1  mrg 
    263  1.1  mrg   /* check inexact flag */
    264  1.1  mrg   mpfr_set_prec (x, 5);
    265  1.1  mrg   mpfr_set_str_binary (x, "1.1001E-2");
    266  1.1  mrg   if ((inexact = test_sqrt (x, x, MPFR_RNDN)))
    267  1.1  mrg     {
    268  1.1  mrg       printf ("Wrong inexact flag: expected 0, got %d\n", inexact);
    269  1.1  mrg       exit (1);
    270  1.1  mrg     }
    271  1.1  mrg 
    272  1.1  mrg   mpfr_set_prec (x, 2);
    273  1.1  mrg   mpfr_set_prec (z, 2);
    274  1.1  mrg 
    275  1.1  mrg   /* checks the sign is correctly set */
    276  1.1  mrg   mpfr_set_si (x, 1,  MPFR_RNDN);
    277  1.1  mrg   mpfr_set_si (z, -1, MPFR_RNDN);
    278  1.1  mrg   test_sqrt (z, x, MPFR_RNDN);
    279  1.1  mrg   if (mpfr_cmp_ui (z, 0) < 0)
    280  1.1  mrg     {
    281  1.1  mrg       printf ("Error: square root of 1 gives ");
    282  1.1  mrg       mpfr_print_binary(z);
    283  1.1  mrg       putchar('\n');
    284  1.1  mrg       exit (1);
    285  1.1  mrg     }
    286  1.1  mrg 
    287  1.1  mrg   mpfr_set_prec (x, 192);
    288  1.1  mrg   mpfr_set_prec (z, 160);
    289  1.1  mrg   mpfr_set_str_binary (z, "0.1011010100000100100100100110011001011100100100000011000111011001011101101101110000110100001000100001100001011000E1");
    290  1.1  mrg   mpfr_set_prec (x, 160);
    291  1.1  mrg   test_sqrt(x, z, MPFR_RNDN);
    292  1.1  mrg   test_sqrt(z, x, MPFR_RNDN);
    293  1.1  mrg 
    294  1.1  mrg   mpfr_set_prec (x, 53);
    295  1.1  mrg   mpfr_set_str (x, "8093416094703476.0", 10, MPFR_RNDN);
    296  1.1  mrg   mpfr_div_2exp (x, x, 1075, MPFR_RNDN);
    297  1.1  mrg   test_sqrt (x, x, MPFR_RNDN);
    298  1.1  mrg   mpfr_set_str (z, "1e55596835b5ef@-141", 16, MPFR_RNDN);
    299  1.1  mrg   if (mpfr_cmp (x, z))
    300  1.1  mrg     {
    301  1.1  mrg       printf ("Error: square root of 8093416094703476*2^(-1075)\n");
    302  1.1  mrg       printf ("expected "); mpfr_dump (z);
    303  1.1  mrg       printf ("got      "); mpfr_dump (x);
    304  1.1  mrg       exit (1);
    305  1.1  mrg     }
    306  1.1  mrg 
    307  1.1  mrg   mpfr_set_prec (x, 33);
    308  1.1  mrg   mpfr_set_str_binary (x, "0.111011011011110001100111111001000e-10");
    309  1.1  mrg   mpfr_set_prec (z, 157);
    310  1.1  mrg   inexact = test_sqrt (z, x, MPFR_RNDN);
    311  1.1  mrg   mpfr_set_prec (x, 157);
    312  1.1  mrg   mpfr_set_str_binary (x, "0.11110110101100101111001011100011100011100001101010111011010000100111011000111110100001001011110011111100101110010110010110011001011011010110010000011001101E-5");
    313  1.1  mrg   if (mpfr_cmp (x, z))
    314  1.1  mrg     {
    315  1.1  mrg       printf ("Error: square root (1)\n");
    316  1.1  mrg       exit (1);
    317  1.1  mrg     }
    318  1.1  mrg   if (inexact <= 0)
    319  1.1  mrg     {
    320  1.1  mrg       printf ("Error: wrong inexact flag (1)\n");
    321  1.1  mrg       exit (1);
    322  1.1  mrg     }
    323  1.1  mrg 
    324  1.1  mrg   /* case prec(result) << prec(input) */
    325  1.1  mrg   mpfr_set_prec (z, 2);
    326  1.1  mrg   for (p = 2; p < 1000; p++)
    327  1.1  mrg     {
    328  1.1  mrg       mpfr_set_prec (x, p);
    329  1.1  mrg       mpfr_set_ui (x, 1, MPFR_RNDN);
    330  1.1  mrg       mpfr_nextabove (x);
    331  1.1  mrg       /* 1.0 < x <= 1.5 thus 1 < sqrt(x) <= 1.23 */
    332  1.1  mrg       inexact = test_sqrt (z, x, MPFR_RNDN);
    333  1.1  mrg       MPFR_ASSERTN(inexact < 0 && mpfr_cmp_ui (z, 1) == 0);
    334  1.1  mrg       inexact = test_sqrt (z, x, MPFR_RNDZ);
    335  1.1  mrg       MPFR_ASSERTN(inexact < 0 && mpfr_cmp_ui (z, 1) == 0);
    336  1.1  mrg       inexact = test_sqrt (z, x, MPFR_RNDU);
    337  1.1  mrg       MPFR_ASSERTN(inexact > 0 && mpfr_cmp_ui_2exp (z, 3, -1) == 0);
    338  1.1  mrg       inexact = test_sqrt (z, x, MPFR_RNDD);
    339  1.1  mrg       MPFR_ASSERTN(inexact < 0 && mpfr_cmp_ui (z, 1) == 0);
    340  1.1  mrg       inexact = test_sqrt (z, x, MPFR_RNDA);
    341  1.1  mrg       MPFR_ASSERTN(inexact > 0 && mpfr_cmp_ui_2exp (z, 3, -1) == 0);
    342  1.1  mrg     }
    343  1.1  mrg 
    344  1.1  mrg   /* corner case rw = 0 in rounding to nearest */
    345  1.1  mrg   mpfr_set_prec (z, GMP_NUMB_BITS - 1);
    346  1.1  mrg   mpfr_set_prec (y, GMP_NUMB_BITS - 1);
    347  1.1  mrg   mpfr_set_ui (y, 1, MPFR_RNDN);
    348  1.1  mrg   mpfr_mul_2exp (y, y, GMP_NUMB_BITS - 1, MPFR_RNDN);
    349  1.1  mrg   mpfr_nextabove (y);
    350  1.1  mrg   for (p = 2 * GMP_NUMB_BITS - 1; p <= 1000; p++)
    351  1.1  mrg     {
    352  1.1  mrg       mpfr_set_prec (x, p);
    353  1.1  mrg       mpfr_set_ui (x, 1, MPFR_RNDN);
    354  1.1  mrg       mpfr_set_exp (x, GMP_NUMB_BITS);
    355  1.1  mrg       mpfr_add_ui (x, x, 1, MPFR_RNDN);
    356  1.1  mrg       /* now x = 2^(GMP_NUMB_BITS - 1) + 1 (GMP_NUMB_BITS bits) */
    357  1.1  mrg       MPFR_ASSERTN (mpfr_mul (x, x, x, MPFR_RNDN) == 0); /* exact */
    358  1.1  mrg       inexact = test_sqrt (z, x, MPFR_RNDN);
    359  1.1  mrg       /* even rule: z should be 2^(GMP_NUMB_BITS - 1) */
    360  1.1  mrg       MPFR_ASSERTN (inexact < 0);
    361  1.1  mrg       MPFR_ASSERTN (mpfr_cmp_ui_2exp (z, 1, GMP_NUMB_BITS - 1) == 0);
    362  1.1  mrg       mpfr_nextbelow (x);
    363  1.1  mrg       /* now x is just below [2^(GMP_NUMB_BITS - 1) + 1]^2 */
    364  1.1  mrg       inexact = test_sqrt (z, x, MPFR_RNDN);
    365  1.1  mrg       MPFR_ASSERTN(inexact < 0 &&
    366  1.1  mrg                    mpfr_cmp_ui_2exp (z, 1, GMP_NUMB_BITS - 1) == 0);
    367  1.1  mrg       mpfr_nextabove (x);
    368  1.1  mrg       mpfr_nextabove (x);
    369  1.1  mrg       /* now x is just above [2^(GMP_NUMB_BITS - 1) + 1]^2 */
    370  1.1  mrg       inexact = test_sqrt (z, x, MPFR_RNDN);
    371  1.1  mrg       if (mpfr_cmp (z, y))
    372  1.1  mrg         {
    373  1.1  mrg           printf ("Error for sqrt(x) in rounding to nearest\n");
    374  1.1  mrg           printf ("x="); mpfr_dump (x);
    375  1.1  mrg           printf ("Expected "); mpfr_dump (y);
    376  1.1  mrg           printf ("Got      "); mpfr_dump (z);
    377  1.1  mrg           exit (1);
    378  1.1  mrg         }
    379  1.1  mrg       if (inexact <= 0)
    380  1.1  mrg         {
    381  1.1  mrg           printf ("Wrong inexact flag in corner case for p = %lu\n", (unsigned long) p);
    382  1.1  mrg           exit (1);
    383  1.1  mrg         }
    384  1.1  mrg     }
    385  1.1  mrg 
    386  1.1  mrg   mpfr_set_prec (x, 1000);
    387  1.1  mrg   mpfr_set_ui (x, 9, MPFR_RNDN);
    388  1.1  mrg   mpfr_set_prec (y, 10);
    389  1.1  mrg   inexact = test_sqrt (y, x, MPFR_RNDN);
    390  1.1  mrg   if (mpfr_cmp_ui (y, 3) || inexact != 0)
    391  1.1  mrg     {
    392  1.1  mrg       printf ("Error in sqrt(9:1000) for prec=10\n");
    393  1.1  mrg       exit (1);
    394  1.1  mrg     }
    395  1.1  mrg   mpfr_set_prec (y, GMP_NUMB_BITS);
    396  1.1  mrg   mpfr_nextabove (x);
    397  1.1  mrg   inexact = test_sqrt (y, x, MPFR_RNDN);
    398  1.1  mrg   if (mpfr_cmp_ui (y, 3) || inexact >= 0)
    399  1.1  mrg     {
    400  1.1  mrg       printf ("Error in sqrt(9:1000) for prec=%d\n", (int) GMP_NUMB_BITS);
    401  1.1  mrg       exit (1);
    402  1.1  mrg     }
    403  1.1  mrg   mpfr_set_prec (x, 2 * GMP_NUMB_BITS);
    404  1.1  mrg   mpfr_set_prec (y, GMP_NUMB_BITS);
    405  1.1  mrg   mpfr_set_ui (y, 1, MPFR_RNDN);
    406  1.1  mrg   mpfr_nextabove (y);
    407  1.1  mrg   mpfr_set (x, y, MPFR_RNDN);
    408  1.1  mrg   inexact = test_sqrt (y, x, MPFR_RNDN);
    409  1.1  mrg   if (mpfr_cmp_ui (y, 1) || inexact >= 0)
    410  1.1  mrg     {
    411  1.1  mrg       printf ("Error in sqrt(1) for prec=%d\n", (int) GMP_NUMB_BITS);
    412  1.1  mrg       mpfr_dump (y);
    413  1.1  mrg       exit (1);
    414  1.1  mrg     }
    415  1.1  mrg 
    416  1.1  mrg   mpfr_clear (x);
    417  1.1  mrg   mpfr_clear (y);
    418  1.1  mrg   mpfr_clear (z);
    419  1.1  mrg }
    420  1.1  mrg 
    421  1.1  mrg static void
    422  1.1  mrg check_inexact (mpfr_prec_t p)
    423  1.1  mrg {
    424  1.1  mrg   mpfr_t x, y, z;
    425  1.1  mrg   mpfr_rnd_t rnd;
    426  1.1  mrg   int inexact, sign;
    427  1.1  mrg 
    428  1.1  mrg   mpfr_init2 (x, p);
    429  1.1  mrg   mpfr_init2 (y, p);
    430  1.1  mrg   mpfr_init2 (z, 2*p);
    431  1.1  mrg   mpfr_urandomb (x, RANDS);
    432  1.1  mrg   rnd = RND_RAND ();
    433  1.1  mrg   inexact = test_sqrt (y, x, rnd);
    434  1.1  mrg   if (mpfr_mul (z, y, y, rnd)) /* exact since prec(z) = 2*prec(y) */
    435  1.1  mrg     {
    436  1.1  mrg       printf ("Error: multiplication should be exact\n");
    437  1.1  mrg       exit (1);
    438  1.1  mrg     }
    439  1.1  mrg   mpfr_sub (z, z, x, rnd); /* exact also */
    440  1.1  mrg   sign = mpfr_cmp_ui (z, 0);
    441  1.1  mrg   if (((inexact == 0) && (sign)) ||
    442  1.1  mrg       ((inexact > 0) && (sign <= 0)) ||
    443  1.1  mrg       ((inexact < 0) && (sign >= 0)))
    444  1.1  mrg     {
    445  1.1  mrg       printf ("Error: wrong inexact flag, expected %d, got %d\n",
    446  1.1  mrg               sign, inexact);
    447  1.1  mrg       printf ("x=");
    448  1.1  mrg       mpfr_print_binary (x);
    449  1.1  mrg       printf (" rnd=%s\n", mpfr_print_rnd_mode (rnd));
    450  1.1  mrg       printf ("y="); mpfr_print_binary (y); puts ("");
    451  1.1  mrg       exit (1);
    452  1.1  mrg     }
    453  1.1  mrg   mpfr_clear (x);
    454  1.1  mrg   mpfr_clear (y);
    455  1.1  mrg   mpfr_clear (z);
    456  1.1  mrg }
    457  1.1  mrg 
    458  1.1  mrg static void
    459  1.1  mrg check_nan (void)
    460  1.1  mrg {
    461  1.1  mrg   mpfr_t  x, got;
    462  1.1  mrg 
    463  1.1  mrg   mpfr_init2 (x, 100L);
    464  1.1  mrg   mpfr_init2 (got, 100L);
    465  1.1  mrg 
    466  1.1  mrg   /* sqrt(NaN) == NaN */
    467  1.1  mrg   MPFR_SET_NAN (x);
    468  1.1  mrg   MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */
    469  1.1  mrg   MPFR_ASSERTN (mpfr_nan_p (got));
    470  1.1  mrg 
    471  1.1  mrg   /* sqrt(-1) == NaN */
    472  1.1  mrg   mpfr_set_si (x, -1L, MPFR_RNDZ);
    473  1.1  mrg   MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */
    474  1.1  mrg   MPFR_ASSERTN (mpfr_nan_p (got));
    475  1.1  mrg 
    476  1.1  mrg   /* sqrt(+inf) == +inf */
    477  1.1  mrg   MPFR_SET_INF (x);
    478  1.1  mrg   MPFR_SET_POS (x);
    479  1.1  mrg   MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */
    480  1.1  mrg   MPFR_ASSERTN (mpfr_inf_p (got));
    481  1.1  mrg 
    482  1.1  mrg   /* sqrt(-inf) == NaN */
    483  1.1  mrg   MPFR_SET_INF (x);
    484  1.1  mrg   MPFR_SET_NEG (x);
    485  1.1  mrg   MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */
    486  1.1  mrg   MPFR_ASSERTN (mpfr_nan_p (got));
    487  1.1  mrg 
    488  1.1  mrg   /* sqrt(-0) == 0 */
    489  1.1  mrg   mpfr_set_si (x, 0L, MPFR_RNDZ);
    490  1.1  mrg   MPFR_SET_NEG (x);
    491  1.1  mrg   MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */
    492  1.1  mrg   MPFR_ASSERTN (mpfr_number_p (got));
    493  1.1  mrg   MPFR_ASSERTN (mpfr_cmp_ui (got, 0L) == 0);
    494  1.1  mrg 
    495  1.1  mrg   mpfr_clear (x);
    496  1.1  mrg   mpfr_clear (got);
    497  1.1  mrg }
    498  1.1  mrg 
    499  1.1  mrg /* check that -1 <= x/sqrt(x^2+s*y^2) <= 1 for rounding to nearest or up
    500  1.1  mrg    with s = 0 and s = 1 */
    501  1.1  mrg static void
    502  1.1  mrg test_property1 (mpfr_prec_t p, mpfr_rnd_t r, int s)
    503  1.1  mrg {
    504  1.1  mrg   mpfr_t x, y, z, t;
    505  1.1  mrg 
    506  1.1  mrg   mpfr_init2 (x, p);
    507  1.1  mrg   mpfr_init2 (y, p);
    508  1.1  mrg   mpfr_init2 (z, p);
    509  1.1  mrg   mpfr_init2 (t, p);
    510  1.1  mrg 
    511  1.1  mrg   mpfr_urandomb (x, RANDS);
    512  1.1  mrg   mpfr_mul (z, x, x, r);
    513  1.1  mrg   if (s)
    514  1.1  mrg     {
    515  1.1  mrg       mpfr_urandomb (y, RANDS);
    516  1.1  mrg       mpfr_mul (t, y, y, r);
    517  1.1  mrg       mpfr_add (z, z, t, r);
    518  1.1  mrg     }
    519  1.1  mrg   mpfr_sqrt (z, z, r);
    520  1.1  mrg   mpfr_div (z, x, z, r);
    521  1.1  mrg   /* Note: if both x and y are 0, z is NAN, but the test below will
    522  1.1  mrg      be false. So, everything is fine. */
    523  1.1  mrg   if (mpfr_cmp_si (z, -1) < 0 || mpfr_cmp_ui (z, 1) > 0)
    524  1.1  mrg     {
    525  1.1  mrg       printf ("Error, -1 <= x/sqrt(x^2+y^2) <= 1 does not hold for r=%s\n",
    526  1.1  mrg               mpfr_print_rnd_mode (r));
    527  1.1  mrg       printf ("x="); mpfr_dump (x);
    528  1.1  mrg       printf ("y="); mpfr_dump (y);
    529  1.1  mrg       printf ("got "); mpfr_dump (z);
    530  1.1  mrg       exit (1);
    531  1.1  mrg     }
    532  1.1  mrg 
    533  1.1  mrg   mpfr_clear (x);
    534  1.1  mrg   mpfr_clear (y);
    535  1.1  mrg   mpfr_clear (z);
    536  1.1  mrg   mpfr_clear (t);
    537  1.1  mrg }
    538  1.1  mrg 
    539  1.1  mrg /* check sqrt(x^2) = x */
    540  1.1  mrg static void
    541  1.1  mrg test_property2 (mpfr_prec_t p, mpfr_rnd_t r)
    542  1.1  mrg {
    543  1.1  mrg   mpfr_t x, y;
    544  1.1  mrg 
    545  1.1  mrg   mpfr_init2 (x, p);
    546  1.1  mrg   mpfr_init2 (y, p);
    547  1.1  mrg 
    548  1.1  mrg   mpfr_urandomb (x, RANDS);
    549  1.1  mrg   mpfr_mul (y, x, x, r);
    550  1.1  mrg   mpfr_sqrt (y, y, r);
    551  1.1  mrg   if (mpfr_cmp (y, x))
    552  1.1  mrg     {
    553  1.1  mrg       printf ("Error, sqrt(x^2) = x does not hold for r=%s\n",
    554  1.1  mrg               mpfr_print_rnd_mode (r));
    555  1.1  mrg       printf ("x="); mpfr_dump (x);
    556  1.1  mrg       printf ("got "); mpfr_dump (y);
    557  1.1  mrg       exit (1);
    558  1.1  mrg     }
    559  1.1  mrg 
    560  1.1  mrg   mpfr_clear (x);
    561  1.1  mrg   mpfr_clear (y);
    562  1.1  mrg }
    563  1.1  mrg 
    564  1.1  mrg #define TEST_FUNCTION test_sqrt
    565  1.1  mrg #define TEST_RANDOM_POS 8
    566  1.1  mrg #include "tgeneric.c"
    567  1.1  mrg 
    568  1.1  mrg int
    569  1.1  mrg main (void)
    570  1.1  mrg {
    571  1.1  mrg   mpfr_prec_t p;
    572  1.1  mrg   int k;
    573  1.1  mrg 
    574  1.1  mrg   tests_start_mpfr ();
    575  1.1  mrg 
    576  1.1  mrg   for (p = MPFR_PREC_MIN; p <= 128; p++)
    577  1.1  mrg     {
    578  1.1  mrg       test_property1 (p, MPFR_RNDN, 0);
    579  1.1  mrg       test_property1 (p, MPFR_RNDU, 0);
    580  1.1  mrg       test_property1 (p, MPFR_RNDA, 0);
    581  1.1  mrg       test_property1 (p, MPFR_RNDN, 1);
    582  1.1  mrg       test_property1 (p, MPFR_RNDU, 1);
    583  1.1  mrg       test_property1 (p, MPFR_RNDA, 1);
    584  1.1  mrg       test_property2 (p, MPFR_RNDN);
    585  1.1  mrg     }
    586  1.1  mrg 
    587  1.1  mrg   check_diverse ("635030154261163106768013773815762607450069292760790610550915652722277604820131530404842415587328", 160, "796887792767063979679855997149887366668464780637");
    588  1.1  mrg   special ();
    589  1.1  mrg   check_nan ();
    590  1.1  mrg 
    591  1.1  mrg   for (p=2; p<200; p++)
    592  1.1  mrg     for (k=0; k<200; k++)
    593  1.1  mrg       check_inexact (p);
    594  1.1  mrg   check_float();
    595  1.1  mrg 
    596  1.1  mrg   check3 ("-0.0", MPFR_RNDN, "0.0");
    597  1.1  mrg   check4 ("6.37983013646045901440e+32", MPFR_RNDN, "5.9bc5036d09e0c@13");
    598  1.1  mrg   check4 ("1.0", MPFR_RNDN, "1");
    599  1.1  mrg   check4 ("1.0", MPFR_RNDZ, "1");
    600  1.1  mrg   check4 ("3.725290298461914062500000e-9", MPFR_RNDN, "4@-4");
    601  1.1  mrg   check4 ("3.725290298461914062500000e-9", MPFR_RNDZ, "4@-4");
    602  1.1  mrg   check4 ("1190456976439861.0", MPFR_RNDZ, "2.0e7957873529a@6");
    603  1.1  mrg   check4 ("1219027943874417664.0", MPFR_RNDZ, "4.1cf2af0e6a534@7");
    604  1.1  mrg   /* the following examples are bugs in Cygnus compiler/system, found by
    605  1.1  mrg      Fabrice Rouillier while porting mpfr to Windows */
    606  1.1  mrg   check4 ("9.89438396044940256501e-134", MPFR_RNDU, "8.7af7bf0ebbee@-56");
    607  1.1  mrg   check4 ("7.86528588050363751914e+31", MPFR_RNDZ, "1.f81fc40f32062@13");
    608  1.1  mrg   check4 ("0.99999999999999988897", MPFR_RNDN, "f.ffffffffffff8@-1");
    609  1.1  mrg   check4 ("1.00000000000000022204", MPFR_RNDN, "1");
    610  1.1  mrg   /* the following examples come from the paper "Number-theoretic Test
    611  1.1  mrg    Generation for Directed Rounding" from Michael Parks, Table 4 */
    612  1.1  mrg 
    613  1.1  mrg   check4 ("78652858805036375191418371571712.0", MPFR_RNDN,
    614  1.1  mrg           "1.f81fc40f32063@13");
    615  1.1  mrg   check4 ("38510074998589467860312736661504.0", MPFR_RNDN,
    616  1.1  mrg           "1.60c012a92fc65@13");
    617  1.1  mrg   check4 ("35318779685413012908190921129984.0", MPFR_RNDN,
    618  1.1  mrg           "1.51d17526c7161@13");
    619  1.1  mrg   check4 ("26729022595358440976973142425600.0", MPFR_RNDN,
    620  1.1  mrg           "1.25e19302f7e51@13");
    621  1.1  mrg   check4 ("22696567866564242819241453027328.0", MPFR_RNDN,
    622  1.1  mrg           "1.0ecea7dd2ec3d@13");
    623  1.1  mrg   check4 ("22696888073761729132924856434688.0", MPFR_RNDN,
    624  1.1  mrg           "1.0ecf250e8e921@13");
    625  1.1  mrg   check4 ("36055652513981905145251657416704.0", MPFR_RNDN,
    626  1.1  mrg           "1.5552f3eedcf33@13");
    627  1.1  mrg   check4 ("30189856268896404997497182748672.0", MPFR_RNDN,
    628  1.1  mrg           "1.3853ee10c9c99@13");
    629  1.1  mrg   check4 ("36075288240584711210898775080960.0", MPFR_RNDN,
    630  1.1  mrg           "1.556abe212b56f@13");
    631  1.1  mrg   check4 ("72154663483843080704304789585920.0", MPFR_RNDN,
    632  1.1  mrg           "1.e2d9a51977e6e@13");
    633  1.1  mrg 
    634  1.1  mrg   check4 ("78652858805036375191418371571712.0", MPFR_RNDZ,
    635  1.1  mrg           "1.f81fc40f32062@13");
    636  1.1  mrg   check4 ("38510074998589467860312736661504.0", MPFR_RNDZ,
    637  1.1  mrg           "1.60c012a92fc64@13");
    638  1.1  mrg   check4 ("35318779685413012908190921129984.0", MPFR_RNDZ, "1.51d17526c716@13");
    639  1.1  mrg   check4 ("26729022595358440976973142425600.0", MPFR_RNDZ, "1.25e19302f7e5@13");
    640  1.1  mrg   check4 ("22696567866564242819241453027328.0", MPFR_RNDZ,
    641  1.1  mrg           "1.0ecea7dd2ec3c@13");
    642  1.1  mrg   check4 ("22696888073761729132924856434688.0", MPFR_RNDZ, "1.0ecf250e8e92@13");
    643  1.1  mrg   check4 ("36055652513981905145251657416704.0", MPFR_RNDZ,
    644  1.1  mrg           "1.5552f3eedcf32@13");
    645  1.1  mrg   check4 ("30189856268896404997497182748672.0", MPFR_RNDZ,
    646  1.1  mrg           "1.3853ee10c9c98@13");
    647  1.1  mrg   check4 ("36075288240584711210898775080960.0", MPFR_RNDZ,
    648  1.1  mrg           "1.556abe212b56e@13");
    649  1.1  mrg   check4 ("72154663483843080704304789585920.0", MPFR_RNDZ,
    650  1.1  mrg           "1.e2d9a51977e6d@13");
    651  1.1  mrg 
    652  1.1  mrg   check4 ("78652858805036375191418371571712.0", MPFR_RNDU,
    653  1.1  mrg           "1.f81fc40f32063@13");
    654  1.1  mrg   check4 ("38510074998589467860312736661504.0", MPFR_RNDU,
    655  1.1  mrg           "1.60c012a92fc65@13");
    656  1.1  mrg   check4 ("35318779685413012908190921129984.0", MPFR_RNDU,
    657  1.1  mrg           "1.51d17526c7161@13");
    658  1.1  mrg   check4 ("26729022595358440976973142425600.0", MPFR_RNDU,
    659  1.1  mrg           "1.25e19302f7e51@13");
    660  1.1  mrg   check4 ("22696567866564242819241453027328.0", MPFR_RNDU,
    661  1.1  mrg           "1.0ecea7dd2ec3d@13");
    662  1.1  mrg   check4 ("22696888073761729132924856434688.0", MPFR_RNDU,
    663  1.1  mrg           "1.0ecf250e8e921@13");
    664  1.1  mrg   check4 ("36055652513981905145251657416704.0", MPFR_RNDU,
    665  1.1  mrg           "1.5552f3eedcf33@13");
    666  1.1  mrg   check4 ("30189856268896404997497182748672.0", MPFR_RNDU,
    667  1.1  mrg           "1.3853ee10c9c99@13");
    668  1.1  mrg   check4 ("36075288240584711210898775080960.0", MPFR_RNDU,
    669  1.1  mrg           "1.556abe212b56f@13");
    670  1.1  mrg   check4 ("72154663483843080704304789585920.0", MPFR_RNDU,
    671  1.1  mrg           "1.e2d9a51977e6e@13");
    672  1.1  mrg 
    673  1.1  mrg   check4 ("78652858805036375191418371571712.0", MPFR_RNDD,
    674  1.1  mrg           "1.f81fc40f32062@13");
    675  1.1  mrg   check4 ("38510074998589467860312736661504.0", MPFR_RNDD,
    676  1.1  mrg           "1.60c012a92fc64@13");
    677  1.1  mrg   check4 ("35318779685413012908190921129984.0", MPFR_RNDD, "1.51d17526c716@13");
    678  1.1  mrg   check4 ("26729022595358440976973142425600.0", MPFR_RNDD, "1.25e19302f7e5@13");
    679  1.1  mrg   check4 ("22696567866564242819241453027328.0", MPFR_RNDD,
    680  1.1  mrg           "1.0ecea7dd2ec3c@13");
    681  1.1  mrg   check4 ("22696888073761729132924856434688.0", MPFR_RNDD, "1.0ecf250e8e92@13");
    682  1.1  mrg   check4 ("36055652513981905145251657416704.0", MPFR_RNDD,
    683  1.1  mrg           "1.5552f3eedcf32@13");
    684  1.1  mrg   check4 ("30189856268896404997497182748672.0", MPFR_RNDD,
    685  1.1  mrg           "1.3853ee10c9c98@13");
    686  1.1  mrg   check4 ("36075288240584711210898775080960.0", MPFR_RNDD,
    687  1.1  mrg           "1.556abe212b56e@13");
    688  1.1  mrg   check4 ("72154663483843080704304789585920.0", MPFR_RNDD,
    689  1.1  mrg           "1.e2d9a51977e6d@13");
    690  1.1  mrg 
    691  1.1  mrg   /* check that rounding away is just rounding toward plus infinity */
    692  1.1  mrg   check4 ("72154663483843080704304789585920.0", MPFR_RNDA,
    693  1.1  mrg           "1.e2d9a51977e6e@13");
    694  1.1  mrg 
    695  1.1  mrg   test_generic (2, 300, 15);
    696  1.1  mrg   data_check ("data/sqrt", mpfr_sqrt, "mpfr_sqrt");
    697  1.1  mrg   bad_cases (mpfr_sqrt, mpfr_sqr, "mpfr_sqrt", 8, -256, 255, 4, 128, 800, 50);
    698  1.1  mrg 
    699  1.1  mrg   tests_end_mpfr ();
    700  1.1  mrg   return 0;
    701  1.1  mrg }
    702