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