Home | History | Annotate | Line # | Download | only in tests
tsqrt.c revision 1.1.1.1
      1 /* Test file for mpfr_sqrt.
      2 
      3 Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
      4 Contributed by the Arenaire and Cacao 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, 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_nan (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_SET_NEG (x);
    491   MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */
    492   MPFR_ASSERTN (mpfr_number_p (got));
    493   MPFR_ASSERTN (mpfr_cmp_ui (got, 0L) == 0);
    494 
    495   mpfr_clear (x);
    496   mpfr_clear (got);
    497 }
    498 
    499 /* check that -1 <= x/sqrt(x^2+s*y^2) <= 1 for rounding to nearest or up
    500    with s = 0 and s = 1 */
    501 static void
    502 test_property1 (mpfr_prec_t p, mpfr_rnd_t r, int s)
    503 {
    504   mpfr_t x, y, z, t;
    505 
    506   mpfr_init2 (x, p);
    507   mpfr_init2 (y, p);
    508   mpfr_init2 (z, p);
    509   mpfr_init2 (t, p);
    510 
    511   mpfr_urandomb (x, RANDS);
    512   mpfr_mul (z, x, x, r);
    513   if (s)
    514     {
    515       mpfr_urandomb (y, RANDS);
    516       mpfr_mul (t, y, y, r);
    517       mpfr_add (z, z, t, r);
    518     }
    519   mpfr_sqrt (z, z, r);
    520   mpfr_div (z, x, z, r);
    521   /* Note: if both x and y are 0, z is NAN, but the test below will
    522      be false. So, everything is fine. */
    523   if (mpfr_cmp_si (z, -1) < 0 || mpfr_cmp_ui (z, 1) > 0)
    524     {
    525       printf ("Error, -1 <= x/sqrt(x^2+y^2) <= 1 does not hold for r=%s\n",
    526               mpfr_print_rnd_mode (r));
    527       printf ("x="); mpfr_dump (x);
    528       printf ("y="); mpfr_dump (y);
    529       printf ("got "); mpfr_dump (z);
    530       exit (1);
    531     }
    532 
    533   mpfr_clear (x);
    534   mpfr_clear (y);
    535   mpfr_clear (z);
    536   mpfr_clear (t);
    537 }
    538 
    539 /* check sqrt(x^2) = x */
    540 static void
    541 test_property2 (mpfr_prec_t p, mpfr_rnd_t r)
    542 {
    543   mpfr_t x, y;
    544 
    545   mpfr_init2 (x, p);
    546   mpfr_init2 (y, p);
    547 
    548   mpfr_urandomb (x, RANDS);
    549   mpfr_mul (y, x, x, r);
    550   mpfr_sqrt (y, y, r);
    551   if (mpfr_cmp (y, x))
    552     {
    553       printf ("Error, sqrt(x^2) = x does not hold for r=%s\n",
    554               mpfr_print_rnd_mode (r));
    555       printf ("x="); mpfr_dump (x);
    556       printf ("got "); mpfr_dump (y);
    557       exit (1);
    558     }
    559 
    560   mpfr_clear (x);
    561   mpfr_clear (y);
    562 }
    563 
    564 #define TEST_FUNCTION test_sqrt
    565 #define TEST_RANDOM_POS 8
    566 #include "tgeneric.c"
    567 
    568 int
    569 main (void)
    570 {
    571   mpfr_prec_t p;
    572   int k;
    573 
    574   tests_start_mpfr ();
    575 
    576   for (p = MPFR_PREC_MIN; p <= 128; p++)
    577     {
    578       test_property1 (p, MPFR_RNDN, 0);
    579       test_property1 (p, MPFR_RNDU, 0);
    580       test_property1 (p, MPFR_RNDA, 0);
    581       test_property1 (p, MPFR_RNDN, 1);
    582       test_property1 (p, MPFR_RNDU, 1);
    583       test_property1 (p, MPFR_RNDA, 1);
    584       test_property2 (p, MPFR_RNDN);
    585     }
    586 
    587   check_diverse ("635030154261163106768013773815762607450069292760790610550915652722277604820131530404842415587328", 160, "796887792767063979679855997149887366668464780637");
    588   special ();
    589   check_nan ();
    590 
    591   for (p=2; p<200; p++)
    592     for (k=0; k<200; k++)
    593       check_inexact (p);
    594   check_float();
    595 
    596   check3 ("-0.0", MPFR_RNDN, "0.0");
    597   check4 ("6.37983013646045901440e+32", MPFR_RNDN, "5.9bc5036d09e0c@13");
    598   check4 ("1.0", MPFR_RNDN, "1");
    599   check4 ("1.0", MPFR_RNDZ, "1");
    600   check4 ("3.725290298461914062500000e-9", MPFR_RNDN, "4@-4");
    601   check4 ("3.725290298461914062500000e-9", MPFR_RNDZ, "4@-4");
    602   check4 ("1190456976439861.0", MPFR_RNDZ, "2.0e7957873529a@6");
    603   check4 ("1219027943874417664.0", MPFR_RNDZ, "4.1cf2af0e6a534@7");
    604   /* the following examples are bugs in Cygnus compiler/system, found by
    605      Fabrice Rouillier while porting mpfr to Windows */
    606   check4 ("9.89438396044940256501e-134", MPFR_RNDU, "8.7af7bf0ebbee@-56");
    607   check4 ("7.86528588050363751914e+31", MPFR_RNDZ, "1.f81fc40f32062@13");
    608   check4 ("0.99999999999999988897", MPFR_RNDN, "f.ffffffffffff8@-1");
    609   check4 ("1.00000000000000022204", MPFR_RNDN, "1");
    610   /* the following examples come from the paper "Number-theoretic Test
    611    Generation for Directed Rounding" from Michael Parks, Table 4 */
    612 
    613   check4 ("78652858805036375191418371571712.0", MPFR_RNDN,
    614           "1.f81fc40f32063@13");
    615   check4 ("38510074998589467860312736661504.0", MPFR_RNDN,
    616           "1.60c012a92fc65@13");
    617   check4 ("35318779685413012908190921129984.0", MPFR_RNDN,
    618           "1.51d17526c7161@13");
    619   check4 ("26729022595358440976973142425600.0", MPFR_RNDN,
    620           "1.25e19302f7e51@13");
    621   check4 ("22696567866564242819241453027328.0", MPFR_RNDN,
    622           "1.0ecea7dd2ec3d@13");
    623   check4 ("22696888073761729132924856434688.0", MPFR_RNDN,
    624           "1.0ecf250e8e921@13");
    625   check4 ("36055652513981905145251657416704.0", MPFR_RNDN,
    626           "1.5552f3eedcf33@13");
    627   check4 ("30189856268896404997497182748672.0", MPFR_RNDN,
    628           "1.3853ee10c9c99@13");
    629   check4 ("36075288240584711210898775080960.0", MPFR_RNDN,
    630           "1.556abe212b56f@13");
    631   check4 ("72154663483843080704304789585920.0", MPFR_RNDN,
    632           "1.e2d9a51977e6e@13");
    633 
    634   check4 ("78652858805036375191418371571712.0", MPFR_RNDZ,
    635           "1.f81fc40f32062@13");
    636   check4 ("38510074998589467860312736661504.0", MPFR_RNDZ,
    637           "1.60c012a92fc64@13");
    638   check4 ("35318779685413012908190921129984.0", MPFR_RNDZ, "1.51d17526c716@13");
    639   check4 ("26729022595358440976973142425600.0", MPFR_RNDZ, "1.25e19302f7e5@13");
    640   check4 ("22696567866564242819241453027328.0", MPFR_RNDZ,
    641           "1.0ecea7dd2ec3c@13");
    642   check4 ("22696888073761729132924856434688.0", MPFR_RNDZ, "1.0ecf250e8e92@13");
    643   check4 ("36055652513981905145251657416704.0", MPFR_RNDZ,
    644           "1.5552f3eedcf32@13");
    645   check4 ("30189856268896404997497182748672.0", MPFR_RNDZ,
    646           "1.3853ee10c9c98@13");
    647   check4 ("36075288240584711210898775080960.0", MPFR_RNDZ,
    648           "1.556abe212b56e@13");
    649   check4 ("72154663483843080704304789585920.0", MPFR_RNDZ,
    650           "1.e2d9a51977e6d@13");
    651 
    652   check4 ("78652858805036375191418371571712.0", MPFR_RNDU,
    653           "1.f81fc40f32063@13");
    654   check4 ("38510074998589467860312736661504.0", MPFR_RNDU,
    655           "1.60c012a92fc65@13");
    656   check4 ("35318779685413012908190921129984.0", MPFR_RNDU,
    657           "1.51d17526c7161@13");
    658   check4 ("26729022595358440976973142425600.0", MPFR_RNDU,
    659           "1.25e19302f7e51@13");
    660   check4 ("22696567866564242819241453027328.0", MPFR_RNDU,
    661           "1.0ecea7dd2ec3d@13");
    662   check4 ("22696888073761729132924856434688.0", MPFR_RNDU,
    663           "1.0ecf250e8e921@13");
    664   check4 ("36055652513981905145251657416704.0", MPFR_RNDU,
    665           "1.5552f3eedcf33@13");
    666   check4 ("30189856268896404997497182748672.0", MPFR_RNDU,
    667           "1.3853ee10c9c99@13");
    668   check4 ("36075288240584711210898775080960.0", MPFR_RNDU,
    669           "1.556abe212b56f@13");
    670   check4 ("72154663483843080704304789585920.0", MPFR_RNDU,
    671           "1.e2d9a51977e6e@13");
    672 
    673   check4 ("78652858805036375191418371571712.0", MPFR_RNDD,
    674           "1.f81fc40f32062@13");
    675   check4 ("38510074998589467860312736661504.0", MPFR_RNDD,
    676           "1.60c012a92fc64@13");
    677   check4 ("35318779685413012908190921129984.0", MPFR_RNDD, "1.51d17526c716@13");
    678   check4 ("26729022595358440976973142425600.0", MPFR_RNDD, "1.25e19302f7e5@13");
    679   check4 ("22696567866564242819241453027328.0", MPFR_RNDD,
    680           "1.0ecea7dd2ec3c@13");
    681   check4 ("22696888073761729132924856434688.0", MPFR_RNDD, "1.0ecf250e8e92@13");
    682   check4 ("36055652513981905145251657416704.0", MPFR_RNDD,
    683           "1.5552f3eedcf32@13");
    684   check4 ("30189856268896404997497182748672.0", MPFR_RNDD,
    685           "1.3853ee10c9c98@13");
    686   check4 ("36075288240584711210898775080960.0", MPFR_RNDD,
    687           "1.556abe212b56e@13");
    688   check4 ("72154663483843080704304789585920.0", MPFR_RNDD,
    689           "1.e2d9a51977e6d@13");
    690 
    691   /* check that rounding away is just rounding toward plus infinity */
    692   check4 ("72154663483843080704304789585920.0", MPFR_RNDA,
    693           "1.e2d9a51977e6e@13");
    694 
    695   test_generic (2, 300, 15);
    696   data_check ("data/sqrt", mpfr_sqrt, "mpfr_sqrt");
    697   bad_cases (mpfr_sqrt, mpfr_sqr, "mpfr_sqrt", 8, -256, 255, 4, 128, 800, 50);
    698 
    699   tests_end_mpfr ();
    700   return 0;
    701 }
    702