(root)/
mpfr-4.2.1/
tests/
tstrtofr.c
       1  /* Test file for mpfr_set_str.
       2  
       3  Copyright 2004-2023 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  https://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 "mpfr-test.h"
      24  
      25  /* The implicit \0 is useless, but we do not write num_to_text[62] otherwise
      26     g++ complains. */
      27  static const char num_to_text36[] = "0123456789abcdefghijklmnopqrstuvwxyz";
      28  static const char num_to_text62[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
      29    "abcdefghijklmnopqrstuvwxyz";
      30  
      31  static void
      32  check_special (void)
      33  {
      34    mpfr_t x, y;
      35    int i, res;
      36    char *s;
      37  
      38    mpfr_init (x);
      39    mpfr_init (y);
      40  
      41    /* Check dummy case */
      42    res = mpfr_strtofr (x, "1234567.89E1", NULL, 10, MPFR_RNDN);
      43    mpfr_set_str (y, "1234567.89E1", 10, MPFR_RNDN);
      44    if (mpfr_cmp (x, y))
      45      {
      46        printf ("Results differ between strtofr and set_str.\n"
      47                " set_str gives: ");
      48        mpfr_dump (y);
      49        printf (" strtofr gives: ");
      50        mpfr_dump (x);
      51        exit (1);
      52      }
      53  
      54    /* Check NAN  */
      55    mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
      56    res = mpfr_strtofr (x, "NaN", &s, 10, MPFR_RNDN);
      57    if (res != 0 || !mpfr_nan_p (x) || *s != 0)
      58      {
      59        printf ("Error for setting NAN (1)\n");
      60        exit (1);
      61      }
      62    mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
      63    res = mpfr_strtofr (x, "+NaN", &s, 10, MPFR_RNDN);
      64    if (res != 0 || !mpfr_nan_p (x) || *s != 0)
      65      {
      66        printf ("Error for setting +NAN (1)\n");
      67        exit (1);
      68      }
      69    mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
      70    res = mpfr_strtofr (x, " -NaN", &s, 10, MPFR_RNDN);
      71    if (res != 0 || !mpfr_nan_p (x) || *s != 0)
      72      {
      73        printf ("Error for setting -NAN (1)\n");
      74        exit (1);
      75      }
      76    mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
      77    res = mpfr_strtofr (x, "@nAn@xx", &s, 16, MPFR_RNDN);
      78    if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "xx") )
      79      {
      80        printf ("Error for setting NAN (2)\n");
      81        exit (1);
      82      }
      83    mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
      84    res = mpfr_strtofr (x, "NAN(abcdEDF__1256)Hello", &s, 10, MPFR_RNDN);
      85    if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "Hello") )
      86      {
      87        printf ("Error for setting NAN (3)\n");
      88        exit (1);
      89      }
      90    mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
      91    res = mpfr_strtofr (x, "NAN(abcdEDF)__1256)Hello", &s, 10, MPFR_RNDN);
      92    if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "__1256)Hello") )
      93      {
      94        printf ("Error for setting NAN (4)\n");
      95        exit (1);
      96      }
      97    mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
      98    res = mpfr_strtofr (x, "NAN(abc%dEDF)__1256)Hello", &s, 10, MPFR_RNDN);
      99    if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "(abc%dEDF)__1256)Hello") )
     100      {
     101        printf ("Error for setting NAN (5)\n");
     102        exit (1);
     103      }
     104    mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
     105    res = mpfr_strtofr (x, "NAN((abc))", &s, 10, MPFR_RNDN);
     106    if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "((abc))") )
     107      {
     108        printf ("Error for setting NAN (6)\n");
     109        exit (1);
     110      }
     111    mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
     112    res = mpfr_strtofr (x, "NAN()foo", &s, 10, MPFR_RNDN);
     113    if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "foo") )
     114      {
     115        printf ("Error for setting NAN (7)\n");
     116        exit (1);
     117      }
     118  
     119    /* Check infinity */
     120    for (i = 0; i <= 0xff; i++)
     121      {
     122        char t[11] = "+@INFINITY";  /* not char *: this will be modified. */
     123        char *p;
     124        int base, j;
     125  
     126        /* Test all the case variants, assuming ASCII or similar.
     127           The first letters are changed first, so that at i = 8,
     128           the 2^3 = 8 "INF" case variants have been tested, and
     129           they don't need to be tested again for i > 8. */
     130        for (j = 0; j < 8; j++)
     131          if ((i >> j) % 2 != 0)
     132            t[j+2] += 'a' - 'A';
     133  
     134        /* Test "INFINITY", "+INFINITY", "-INFINITY",
     135                "INF", "+INF", "-INF",
     136                "@INF@", "+@INF@", "-@INF@",
     137           up to case changes. */
     138        for (j = 0; j < 9; j++)
     139          {
     140            if (j == 3)
     141              {
     142                /* At i = 8, we have tested all the "INF" case variants. */
     143                if (i >= 8)
     144                  break;
     145                t[5] = '\0';
     146              }
     147            if (j == 6)
     148              {
     149                t[1] = '@';
     150                t[5] = '@';
     151                t[6] = '\0';
     152              }
     153            if (j % 3 == 1)
     154              t[j != 7] = '+';
     155            if (j % 3 == 2)
     156              t[j != 8] = '-';
     157            p = t + (j % 3 == 0) + (j < 6);
     158            base = randlimb () % (j < 6 ? 17 : 63);
     159            if (base == 1)
     160              base = 0;
     161            res = mpfr_strtofr (x, p, &s, base, MPFR_RNDN);
     162            if (res != 0 || !mpfr_inf_p (x) || *s != 0 ||
     163                (j % 3 != 2 ? MPFR_IS_NEG (x) : MPFR_IS_POS (x)))
     164              {
     165                printf ("Error for setting \"%s\" in base %d\n s=\"%s\"\n x=",
     166                        p, base, s);
     167                mpfr_dump (x);
     168                exit (1);
     169              }
     170          }
     171      }
     172    res = mpfr_strtofr (x, "INFANITY", &s, 8, MPFR_RNDN);
     173    if (res != 0 || !mpfr_inf_p (x) || strcmp(s, "ANITY"))
     174      {
     175        printf ("Error for setting INFINITY (2)\n s=%s\n x=", s);
     176        mpfr_dump (x);
     177        exit (1);
     178      }
     179    res = mpfr_strtofr (x, "@INF@*2", &s, 11, MPFR_RNDN);
     180    if (res != 0 || !mpfr_inf_p (x) || strcmp(s, "*2"))
     181      {
     182        printf ("Error for setting INFINITY (3)\n s=%s\n x=", s);
     183        mpfr_dump (x);
     184        exit (1);
     185      }
     186  
     187    /* Check Zero */
     188    res = mpfr_strtofr (x, " 00000", &s, 11, MPFR_RNDN);
     189    if (res != 0 || !mpfr_zero_p (x) || s[0] != 0)
     190      {
     191        printf ("Error for setting ZERO (1)\n s=%s\n x=", s);
     192        mpfr_dump (x);
     193        exit (1);
     194      }
     195  
     196    /* Check base 62 */
     197    res = mpfr_strtofr (x, "A", NULL, 62, MPFR_RNDN);
     198    if (res != 0 || mpfr_cmp_ui (x, 10))
     199      {
     200        printf ("Error for setting 'A' in base 62\n x=");
     201        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
     202        putchar ('\n');
     203        exit (1);
     204      }
     205    res = mpfr_strtofr (x, "a", NULL, 62, MPFR_RNDN);
     206    if (res != 0 || mpfr_cmp_ui (x, 36))
     207      {
     208        printf ("Error for setting 'a' in base 62\n x=");
     209        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
     210        putchar ('\n');
     211        exit (1);
     212      }
     213    res = mpfr_strtofr (x, "Z", NULL, 62, MPFR_RNDN);
     214    if (res != 0 || mpfr_cmp_ui (x, 35))
     215      {
     216        printf ("Error for setting 'Z' in base 62\n x=");
     217        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
     218        putchar ('\n');
     219        exit (1);
     220      }
     221    res = mpfr_strtofr (x, "z", NULL, 62, MPFR_RNDN);
     222    if (res != 0 || mpfr_cmp_ui (x, 61))
     223      {
     224        printf ("Error for setting 'z' in base 62\n x=");
     225        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
     226        putchar ('\n');
     227        exit (1);
     228      }
     229    res = mpfr_strtofr (x, "ZA", NULL, 62, MPFR_RNDN);
     230    if (res != 0 || mpfr_cmp_ui (x, 2180))
     231      {
     232        printf ("Error for setting 'ZA' in base 62\n x=");
     233        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
     234        putchar ('\n');
     235        exit (1);
     236      }
     237    res = mpfr_strtofr (x, "za", NULL, 62, MPFR_RNDN);
     238    if (res != 0 || mpfr_cmp_ui (x, 3818))
     239      {
     240        printf ("Error for setting 'za' in base 62\n x=");
     241        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
     242        putchar ('\n');
     243        exit (1);
     244      }
     245    res = mpfr_strtofr (x, "aZ", NULL, 62, MPFR_RNDN);
     246    if (res != 0 || mpfr_cmp_ui (x, 2267))
     247      {
     248        printf ("Error for setting 'aZ' in base 62\n x=");
     249        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
     250        putchar ('\n');
     251        exit (1);
     252      }
     253    res = mpfr_strtofr (x, "Az", NULL, 62, MPFR_RNDN);
     254    if (res != 0 || mpfr_cmp_ui (x, 681))
     255      {
     256        printf ("Error for setting 'Az' in base 62\n x=");
     257        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
     258        putchar ('\n');
     259        exit (1);
     260      }
     261  
     262    /* Check base 60 */
     263    res = mpfr_strtofr (x, "Aa", NULL, 60, MPFR_RNDN);
     264    if (res != 0 || mpfr_cmp_ui (x, 636))
     265      {
     266        printf ("Error for setting 'Aa' in base 60\n x=");
     267        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
     268        putchar ('\n');
     269        exit (1);
     270      }
     271    res = mpfr_strtofr (x, "Zz", &s, 60, MPFR_RNDN);
     272    if (res != 0 || mpfr_cmp_ui (x, 35) || strcmp(s, "z") )
     273      {
     274        printf ("Error for setting 'Zz' in base 60\n x=");
     275        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
     276        putchar ('\n');
     277        exit (1);
     278      }
     279  
     280    /* Check base 61 */
     281    res = mpfr_strtofr (x, "z", &s, 61, MPFR_RNDN);
     282    if (res != 0 || mpfr_cmp_ui (x, 0) || strcmp(s, "z") )
     283      {
     284        printf ("Error for setting 'z' in base 61\n x=");
     285        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
     286        putchar ('\n');
     287        exit (1);
     288      }
     289  
     290    mpfr_clear (x);
     291    mpfr_clear (y);
     292  }
     293  
     294  /* The following RefTable has been generated by this following code */
     295  #if 0
     296  #define MAX_NUM 100
     297  
     298  int randomab (int a, int b)
     299  {
     300    return a + rand () % (b-a);
     301  }
     302  
     303  int
     304  main (void)
     305  {
     306    int i, base;
     307    mpfr_t x;
     308    mpfr_prec_t p;
     309    mpfr_exp_t e;
     310  
     311    mpfr_init (x);
     312    printf ("struct dymmy_test { \n"
     313            " mpfr_prec_t prec; \n"
     314            " int base; \n"
     315            " const char *str; \n"
     316            " const char *binstr; \n"
     317            " } RefTable[] = { \n");
     318    for (i = 0 ; i < MAX_NUM ; i++)
     319      {
     320        p = randomab(2, 180);
     321        base = randomab (2, 30);
     322        e = randomab (-1<<15, 1<<15);
     323        mpfr_set_prec (x, p);
     324        mpfr_urandomb (x, RANDS);
     325        mpfr_mul_2si (x, x, e, MPFR_RNDN);
     326        printf("{%lu, %d,\n\"", p, base);
     327        mpfr_out_str (stdout, base, p, x, MPFR_RNDN);
     328        printf ("\",\n\"");
     329        mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
     330        printf ("\"}%c\n", i == MAX_NUM-1 ? ' ' : ',' );
     331      }
     332    printf("};\n");
     333    mpfr_clear (x);
     334  }
     335  #endif
     336  
     337  static struct dymmy_test {
     338   mpfr_prec_t prec;
     339   int base;
     340   const char *str;
     341   const char *binstr;
     342   } RefTable[] = {
     343  {39, 20,
     344  "1.1c9jeh9jg12d8iiggf26b8ce2cig24agai51d9@1445",
     345  "1.00111010111010001110110001101011101011e6245"},
     346  {119, 3,
     347  "1.2210112120221020220021000020101121120011021202212101222000011110211211122222001001221110102220122021121021101010120101e-5655",
     348  "1.1111101110011110001101011100011000011100001011011100010011010010001000000111001010000001110111010100011000110010000000e-8963"},
     349  {166, 18,
     350  "3.ecg67g31434b74d8hhbe2dbbb46g9546cae72cae0cfghfh00ed7gebe9ca63b47h08bgbdeb880a76dea12he31e1ccd67e9dh22a911b46h517b745169b2g43egg2e4eah820cdb2132d6a4f9c63505dd4a0dafbc@-5946",
     351  "1.011110010000110011111011111100110110010110000010100001101111111000010000011111110101100000010110011001100000010001100101000001101000010010001011001011000110100011001e-24793"},
     352  {139, 4,
     353  "1.020302230021023320300300101212330121100031233000032101123133120221012000000000000000000000000000000000000000000000000000000000000000000000e11221",
     354  "1.001000110010101100001001001011111000110000110000010001100110111100011001010000001101101111000000001110010001011011011111011000101001000110e22442"},
     355  {126, 13,
     356  "4.a3cb351c6c548a0475218519514c6c54366681447019ac70a387862c39c86546ab27608c9c2863328860aa2464288070a76c0773882728c5213a335289259@2897",
     357  "1.01011010000001110001100001101111100111011010010111000011000101111011000100001010010100110111101001001001000000011100010000000e10722"},
     358  {6, 26,
     359  "1.j79f6@-1593",
     360  "1.00000e-7487"},
     361  {26, 18,
     362  "3.5e99682hh310aa89hb2fb4h88@-5704",
     363  "1.0110010100010101000101100e-23784"},
     364  {12, 21,
     365  "4.j7f3e2ccdfa@-3524",
     366  "1.10110101011e-15477"},
     367  {38, 28,
     368  "o.agr0m367b9bmm76rplg7b53qlj7f02g717cab@6452",
     369  "1.1001010011101100110100111000111010001e31021"},
     370  {75, 17,
     371  "4.00abd9gc99902e1cae2caa7647gcc029g01370e96d3f8e9g02f814d3ge5faa29d40b9db470@5487",
     372  "1.11100000110101010111101001110001001010111111010100000100001010100111011101e22429"},
     373  {91, 16,
     374  "1.0a812a627160014a3bda1f00000000000000000000000000000000000000000000000000000000000000000000@7897",
     375  "1.000010101000000100101010011000100111000101100000000000010100101000111011110110100001111100e31588"},
     376  {154, 19,
     377  "1.989279dda02a8ic15e936ahig3c695f6059a3i01b7d1ge6a418bf84gd87e36061hb2bi62ciagcgb9226fafea41d2ig1e2f0a10ea3i40d6dahf598bdbh372bdf5901gh276866804ah53b6338bi@5285",
     378  "1.110101101101101111110010001011110001100000010100011101101001000100110100000011110111000011011101011110010100110101011011111100101101001100000101101000010e22450"},
     379  {53, 2,
     380  "1.0100010111100111001010000100011011111011011100110111e-20319",
     381  "1.0100010111100111001010000100011011111011011100110111e-20319"},
     382  {76, 3,
     383  "2.101212121100222100012112101120011222102000021110201110000202111122221100001e1511",
     384  "1.000110101010111000011001011111110000001001101001011011111110111111010000111e2396"},
     385  {31, 9,
     386  "1.171774371505084376877631528681e3258",
     387  "1.110101101011111011111000110011e10327"},
     388  {175, 8,
     389  "4.506242760242070533035566017365410474451421355546570157251400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e3483",
     390  "1.001010001100101000101111100000101000100001110001010110110000111011011101100000011110111101011000010001001111001001010011000100010111011011011001101011110000011011110101010011e10451"},
     391  {103, 24,
     392  "8.0hmlm3g183cj358fn4bimn5bie1l89k95m647474mm8jg5kh1c011gi0m7de9j7b48c595g1bki4n32kll7b882eg7klgga0h0gf11@4510",
     393  "1.001000110101001101011010101001111010110100010100110101010101110000001011001101110110010111000101010111e20681"},
     394  {12, 9,
     395  "3.00221080453e2479",
     396  "1.11000111010e7859"},
     397  {86, 11,
     398  "6.873680186953174a274754118026423965415553a088387303452447389287133a0956111602a5a085446@5035",
     399  "1.0000000000110100010110000111010001010100101011000100101010010011101010000110011110001e17421"},
     400  {68, 10,
     401  "6.1617378719016284192718392572980535262609909598793237475124371481233e481",
     402  "1.0110001011000101110010111101100101111110001100001011110011001101111e1600"},
     403  {11, 15,
     404  "5.ab10c18d45@907",
     405  "1.0000101111e3546"},
     406  {77, 26,
     407  "6.e6kl84g6h30o3nfnj7fjjff4n1ee6e5iop76gabj23e7hgan9o6724domc7bp4hdll95g817519f@5114",
     408  "1.1011000101111111111110011011101100000100101000001001100000001011010001001000e24040"},
     409  {28, 27,
     410  "d.odiqp9kgh84o8d2aoqg4c21hemi@3566",
     411  "1.101001111001111111110011110e16959"},
     412  {45, 14,
     413  "7.cddc6295a576980adbc8c16111d6301bad3146a1143c@-6227",
     414  "1.10000000110011000000101100110001011100010111e-23706"},
     415  {54, 19,
     416  "1.b6e67i2124hfga2g819g1d6527g2b603eg3cd8hhca9gecig8geg1@4248",
     417  "1.11010100100010101101110110010100000010111010010101110e18045"},
     418  {49, 20,
     419  "1.jj68bj6idadg44figi10d2ji99g6ddi6c6ich96a5h86i529@-3149",
     420  "1.001011111101100100001010001000011100000000101110e-13609"},
     421  {171, 16,
     422  "6.22cf0e566d8ff11359d70bd9200065cfd72600b12e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000@5602",
     423  "1.10001000101100111100001110010101100110110110001111111100010001001101011001110101110000101111011001001000000000000001100101110011111101011100100110000000001011000100101110e22410"},
     424  {144, 14,
     425  "1.425d9709b4c125651ab88bb1a0370c14270d067a9a74a612dad48d5c025531c175c1b905201d0d9773aa686c8249db9c0b841b10821791c02baa2525a4aa7571850439c2cc965cd@-3351",
     426  "1.11100111110001001101010111010000101010011000111001101011000001011110101110011011100100111001101101111011001001101011001101001011011101101111011e-12759"},
     427  {166, 6,
     428  "3.324252232403440543134003140400220120040245215204322153511143504542403430152410543444455151104314552352030352125540101550151410414122051500201022252511512332523431554e8340",
     429  "1.010101111101111101001001110010111110010000001111010101100110011011010110011001001100001111010101100000010111011111101110110111101110010001110001111000001010001111000e21560"},
     430  {141, 24,
     431  "2.i3c88lkm2958l9ncb9f85kk35namjli84clek5j6jjkli82kb9m4e4i2g39me63db2094cif80gcba8ie6l15ia0d667kn9i1f77bdak599e1ach0j05cdn8kf6c6kfd82j2k6hj2c4d@4281",
     432  "1.10011100001010110111001000000000101011100010101011001010001101110100110111011000111101000001111101100000110100100010101011001100100011001011e19629"},
     433  {84, 6,
     434  "2.41022133512503223022555143021524424430350133500020112434301542311050052304150111243e982",
     435  "1.11010001111111001010011100011000011100100111111010001111010010101001001000011100001e2539"},
     436  {56, 9,
     437  "1.5305472255016741401411184703518332515066156086511016413e2936",
     438  "1.0111110010001101000000110101110000110101001011001100111e9307"},
     439  {18, 8,
     440  "3.63542400000000000e-599",
     441  "1.11100111011000101e-1796"},
     442  {111, 13,
     443  "8.b693ac7a24679b98708a0057a6202c867bc146740ab1971b380756a24c99804b63436419239ba0510030b819933771a636c57c5747b883@-6160",
     444  "1.01011011111110100101110010100100000110000011011101001110010110000011101110111111010111000011011101101001100100e-22792"},
     445  {162, 16,
     446  "4.f2abe958a313566adbf3169e55cdcff3785dbd5c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000@382",
     447  "1.00111100101010101111101001010110001010001100010011010101100110101011011011111100110001011010011110010101011100110111001111111100110111100001011101101111010101110e1530"},
     448  {117, 23,
     449  "2.4b6kk3ag3if217ih1hggkk69bmcecfil1cd38dijh35j8e6ckhd335a4gj7l05bedk19473i8449b1ajc3jd3ka95eceheh72lh2jh17jamlm1142gll@-3628",
     450  "1.10010010001010001110011000010000011111011101111100110101100100101111101110010011101001111010100010001111110100101111e-16411"},
     451  {179, 2,
     452  "1.1101101011111010101000110101010101101110001011011010101001110111011010011110001000000110101100010010001110010110011000000110001011111001011110100011101000110001001000110100100110e14203",
     453  "1.1101101011111010101000110101010101101110001011011010101001110111011010011110001000000110101100010010001110010110011000000110001011111001011110100011101000110001001000110100100110e14203"},
     454  {18, 27,
     455  "4.ll743n2f654gh3154@-6039",
     456  "1.01101001111010011e-28713"},
     457  {178, 15,
     458  "1.e5443105cad2d014b700c42aa3de854c4b95322420695d07db3564ec07473da83bde123b74c794139265a838ebeca745ad3dc97d7c356271ca935ea8e83306562c2a8edc6e886c1b6b2d3e17038379c33826526770985c068@821",
     459  "1.011100001000101100111111111111000100110111110011101010001111011001111101111001010011100100100101100011101001000000101001010100011111001011001010011101101001000111111010101101011e3208"},
     460  {161, 22,
     461  "2.46ikji624bg042877h8g2jdki4ece6ede62841j7li843a4becdkkii86c54192jkefehikkb3kcb26ij1b3k9agfbb07dih88d6ej0ee0d63i8hedc7f0g0i9g7jf9gf6423j70h421bg5hf2bja9j0a432lb10@-5125",
     462  "1.0111011000111110000010011100001100100110001011101001011110111010100000011100000010011101011100101100111100110000001101010101011110100011101111001011001111100000e-22854"},
     463  {62, 19,
     464  "7.bgd1g0886a6c3a9ee67cc7g3bgf718i98d90788idi5587358e660iffc0ic6@3257",
     465  "1.0101100100001110000100010110100100000111110001111001011110100e13838"},
     466  {127, 19,
     467  "1.413bgf99eidba75ged25f7187080bce3h7ebdeghea4ig6c79g94di7b42a3e4cdi4ic6a53i71d2e4hdbe50ih0a0egf2fi469732131ig6g496bf7h8g3c86ie7h@-4465",
     468  "1.001101111000011011100010010010010110111001001001110011110101111111000001110101111110001110010000110011111101000011000101111101e-18967"},
     469  {17, 21,
     470  "4.7d5b70gh4k0gj4fj@-116",
     471  "1.1000100010000110e-508"},
     472  {141, 13,
     473  "2.2b4988c5cb57072a6a1a9c42224794a1cbc175a9bc673bb28aa045c3182b9396ca8bb8590969672b0239608a845a2c35c08908a58c2a83748c89241a6561422c7cc4866c8454@4358",
     474  "1.10010110101000001000001001111001000100111110100010100110111011111011010010101000110101110000111100010000101101000110000000000001111110110011e16127"},
     475  {39, 7,
     476  "3.00350342452505221136410100232265245244e202",
     477  "1.10011000111110011010100110101101010010e568"},
     478  {119, 24,
     479  "5.2aene587kc2d9a55mm8clhn4dn0a551de58b1fcli8e8hf1jlm7i0376dl5fhb2k8acka03077mnbn9d4dmi0641dce871c81g2b3ge76m3kngm4a9g5gh@-892",
     480  "1.0111101010010100001001111110000000100101110010010111111100100101100001010010100110111000101100101010111000101111000010e-4088"},
     481  {41, 14,
     482  "5.c3dc5c49373d0c0075624931133022185bd08b16@-5294",
     483  "1.0101011000010111111111000010100110011111e-20154"},
     484  {41, 6,
     485  "3.2411143454422033245255450304104450302500e2250",
     486  "1.1110111101010101001001100000100011110111e5817"},
     487  {17, 13,
     488  "3.65789aa26aa273b1@-4490",
     489  "1.1100011101010111e-16614"},
     490  {10, 26,
     491  "1.5p4hag1fl@6017",
     492  "1.110010111e28282"},
     493  {130, 11,
     494  "2.606a72601843700427667823172635a47055021a0a68a99326875195a179483948407aa13726244552332114a1784aaa7239956521604460876871a65708458aa@-6285",
     495  "1.110001001110111110110111000010101000110010011110010101100100001000101011010010000001000101000110111111110101000100000111100010100e-21742"},
     496  {29, 20,
     497  "j.4356d9b7i38i955jjj1j442501bj@163",
     498  "1.1010101011110011100000100100e708"},
     499  {140, 21,
     500  "9.2f5k7aid6bj2b2g5bff29i73hk3a8d8g0i7ifa07hkb79g4hd3c7j6g4hjj2jbhai01gkje3h9g3gj3i34f0194kaed32iea9dcgcj8h7i1khdkf965c1ak97gf3h03fcab3ggi03fa@4864",
     501  "1.0101011100011101000110101001010011111111010011000111111111100000011011100111010001100101100110001110001001100101001100110000011110100101101e21367"},
     502  {133, 13,
     503  "2.3721a9107307a71c75c07c83b70a25a9853619030b5bcb55101ca5c2060bca46c331b92b33aa957c3ac7c817335287c6917999c38c3806b6b5919623023ac52063bb@6602",
     504  "1.011001101111100001100100110100010100010011100010111110110100100000000010011101001011000100000110011011101001010010011110111100010010e24431"},
     505  {118, 2,
     506  "1.001010111011011000100010001110111000001100101000101101010001110110000111101110111011011101111100110010000101001001001e18960",
     507  "1.001010111011011000100010001110111000001100101000101101010001110110000111101110111011011101111100110010000101001001001e18960"},
     508  {102, 23,
     509  "l.26lhk42clcm9g940eihakhi32gb3331lld488cf1j4f73ge051bfl8gcmcg78gkjc2iibjf752eag0dee6dafa97k79jlh11j3270@-2160",
     510  "1.01101011011000100101110111110001011000101101011001011111001101000110111010000010011111101110101100010e-9767"},
     511  {156, 18,
     512  "b.eb927dd4g48abee3cc2begehb9c3b8h83cae152db850ac2f3g816d6787825122c8h3aa3g8023h23000a8hg61065b3e367ac59ca373067730f96dd0d3b73b3c43fef91750b333gd497b8ce9228e7@5504",
     513  "1.11000110111100011101100011001001110011101100011111010100101110010010010011111001100000011010011111111011001011111010001001011001110001100001101000000110000e22954"},
     514  {158, 5,
     515  "3.0112043214104344433122444210142004032004444213123303302023242414000243311324332203224340334422234000104132020124210141322013240010134130441413233111204013422e-10468",
     516  "1.1001011000111111110100100101110011100001110100101001101110011001101001101011010010111010111111101010100011100010101100110111011101000110110100000111001100011e-24305"},
     517  {7, 9,
     518  "2.141540e-146",
     519  "1.001111e-462"},
     520  {111, 5,
     521  "3.21233234110011204313222402442032333320324004133424222041314021020411320312421014434003440431230413141402230403e7641",
     522  "1.10010000000101010000101010101011011010000100010010010000010110001111000111111111000110111001100101101110101101e17743"},
     523  {76, 13,
     524  "7.1c0861453a4ac156b6119ba7548251b5cb00b7c409c2bb8138214676468c9949676226013c1@4639",
     525  "1.001000011000000011101101101010100010010001010111100110010101111110110010111e17169"},
     526  {6, 25,
     527  "c.aj660@-6978",
     528  "1.11000e-32402"},
     529  {156, 3,
     530  "2.22101000022222000012110122210202211110020121210120112102122121111210000211020001020201202200011021211102012110220222110022001121011022011202000110120021012e-14744",
     531  "1.11010001111000101111110000010011001101000100010010110011100100110001100111011101011111111100011111001100001111100101100000001000001100000000010010001011101e-23368"},
     532  {7, 23,
     533  "1.4hclk2@2148",
     534  "1.110110e9716"},
     535  {69, 11,
     536  "2.77684920493191632416690544493465617a187218365952a6740034288687745a26@3263",
     537  "1.01111000111000001111001110000110000110001111110011101100101111011100e11289"},
     538  {146, 21,
     539  "3.agg4d0dj636d526d4i8643ch5jee4ge2c3i46k121857dbedagd98cjifaf0fgc09ca739g2fkfbfh06i687kic2kb8c7i48gda57bb6d9bh81eh49h0d8e3i7ad2kgb1ek86b86g3589k27d@3562",
     540  "1.0010111111111100101010101010001100110101010011011100001110111000101101001110001110010100000001010001000111010000010011110100010010101100101000001e15647"},
     541  {20, 3,
     542  "1.2000000021102111102e-16642",
     543  "1.1011101011111110000e-26377"},
     544  {68, 13,
     545  "1.a43205b2164676727806614acc0398925569c3962a3ba419881a5c63b651aa3ab46@-618",
     546  "1.1111011000001110010100111000110010110110011001110001100101011111000e-2287"},
     547  {129, 4,
     548  "2.22033002012102010122130132103000303000120122313322000222121000300000000000000000000000000000000000000000000000000000000000000000e13222",
     549  "1.01010001111000010000110010010000100011010011100011110010011000000110011000000011000011010110111111010000000101010011001000000110e26445"},
     550  {22, 6,
     551  "1.420033001013011530142e11704",
     552  "1.001000110010110110001e30255"},
     553  {108, 6,
     554  "1.03345424443433104422104400512453214240453335230205104304115343030341144544051005432030344054100542125304500e7375",
     555  "1.00101101110001011101101111000010101011101000001111001110001101100000111100010101010101101100011110111010000e19064"},
     556  {91, 27,
     557  "2.ao077kf8oqoihn5pm6f5eqdcgnd2132d7p6n7di8ep82a1a9be99pm36g1emacbenaeiqphpgpdjhmm9ke3pn4pdea@-5482",
     558  "1.111101100001000011101010001000000111000100100111110010101101110001101101101101101010111110e-26066"},
     559  {96, 9,
     560  "8.25805186310703506315505842015248775712246416686874260383701323213202658278523870037877823670166e-8134",
     561  "1.11010111111000011100111001011010001110010001011101011101110101000101100100100010110011001010000e-25782"},
     562  {161, 16,
     563  "7.3a7627c1e42ef738698e292f0b81728c4b14fe8c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000@-3342",
     564  "1.1100111010011101100010011111000001111001000010111011110111001110000110100110001110001010010010111100001011100000010111001010001100010010110001010011111110100011e-13366"},
     565  {90, 3,
     566  "2.10212200011211012002002221112120210222002020100202111000211012122020011102022112222021001e-3447",
     567  "1.11100010111011011000101111110001000101000111110001100001010111101101011011110001000010001e-5463"},
     568  {100, 27,
     569  "a.f81hjjakdnc021op6ffh530ec8ige6n2fqc8f8j7ia7qelebgqkm4ic5ohh652hq1kgpag6pp0ldin6ce1fg6mj34077f5qc5oe@6576",
     570  "1.011101001010010011110001100011111111010001110110100100101001010000101011101011110010010011111100000e31271"},
     571  {152, 16,
     572  "e.37ac48a0303f903c9d20883eddea4300d1190000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000@-1388",
     573  "1.1100011011110101100010010001010000000110000001111111001000000111100100111010010000010001000001111101101110111101010010000110000000011010001000110010000e-5549"},
     574  {106, 20,
     575  "1.3g2h7i2776d50gjibi937f8cdci3idecdeh3j2gba0j8d1ghgg3eg609ji55h5g7jeai1bii3a4f9jhjfij6jd1g3cg0f6024e252gc3e@6422",
     576  "1.100110000101011010100111100110000000100101000110110011010010000101000100110010001110011110111100010000111e27755"},
     577  {23, 17,
     578  "9.f72e724454d1g0f60g93g6@-6563",
     579  "1.0011100011110110010001e-26823"},
     580  {98, 6,
     581  "1.2444223304453415235424343034030405514010421403514410005234221430055051205523402412055242134042045e-8535",
     582  "1.1101110011010001101001001111100101111010100111001011110001000010100101101110011011101100000111011e-22063"},
     583  {4, 18,
     584  "1.gec@-6711",
     585  "1.100e-27984"},
     586  {69, 24,
     587  "8.d45gdfnhkhb7a20nj96dnggic83imhjne0cceldechn1m4e9fbd9db0ablngjf9n7810@6975",
     588  "1.00100111111100101100110011110110110000110110110010100101011111000100e31983"},
     589  {122, 8,
     590  "4.0227760456667717717077553523466457265600000000000000000000000000000000000000000000000000000000000000000000000000000000000e-1767",
     591  "1.0000001001011111111000010010111011011011111100111111100111100011111110110101110101001110011011010010111101011010111000000e-5299"},
     592  {144, 23,
     593  "8.b01c48dg20bek9a5k376clc501aecg92bdjaeji2dm9230i7j3k36jm50b0c5a0753i2b18534cji34bcl2li033cc534m52k2gbegc25a5g30lf4calag58026i5d7li61jg9digj5ceb1@-4456",
     594  "1.00010000110011010111011011110111001101111001010110001101011100100101101110110000010011011111100000100110001001001111111011010110000000001111110e-20154"},
     595  {111, 4,
     596  "2.23100111310122202021232133233012212012232222323230133100000000000000000000000000000000000000000000000000000000e-10458",
     597  "1.01011010000010101110100011010100010001001101110011111101111000110100110000110101110101010111011101100011111010e-20915"},
     598  {117, 10,
     599  "1.61207328685870427963864999744776917701013812304254540861834226053316419217753608451422967376154318603744156166920074e-6440",
     600  "1.01100011000100111001100010000000110010100001001011111010100001101111100100101100111010100011101110001010011010010010e-21393"},
     601  {106, 16,
     602  "1.dd30a1d24091263243ca1c144f0000000000000000000000000000000000000000000000000000000000000000000000000000000@354",
     603  "1.110111010011000010100001110100100100000010010001001001100011001001000011110010100001110000010100010011110e1416"},
     604  {77, 14,
     605  "4.90d6913ba57b149d8d85a58c311b4d537c10bd7d3c10d69c62bc08d32269760126a58115a105@-7311",
     606  "1.1001000000111100000111001001011000110101001111100001100111010100010000011111e-27834"},
     607  {8, 4,
     608  "3.2230000e15197",
     609  "1.1101011e30395"},
     610  {81, 24,
     611  "1.84ni25h558abmhg2dk7bl2jbbmkf4i8i2bemc5cgmk9jf301c00k24271m9h7mgm4301be1lnldn4364@2573",
     612  "1.01110010011000110110100101011001011111101111101100010110101101011101100001000010e11797"},
     613  {94, 2,
     614  "1.010010010101111001001011111111100100011110110100010001101111111100100101101100110101001011111e32427",
     615  "1.010010010101111001001011111111100100011110110100010001101111111100100101101100110101001011111e32427"},
     616  {77, 21,
     617  "1.87e4k9df85g50ead6fcj4h86820ikdjdjg93d90ca406g470hhkh7ciaba1aggg753g36553ebh5@2538",
     618  "1.0010001100011000111010000010011001010011000000100101010001100000111101000111e11148"},
     619  {80, 17,
     620  "1.923gga999230g94fce02efg753ce001045a35e0264c9c2cb17850e32484fc3526dcg38ed874g5f2@3392",
     621  "1.0011100111101001001101111001110100001100111110011110110001100110101010111001110e13865"},
     622  {99, 7,
     623  "4.53646362336126606650465342500160461331562113222506144210636341332436342025203333264316511653025011e-5540",
     624  "1.01101101111001001100001101101101010011001001100110111000010000101000011001001001101000011101011001e-15551"},
     625  {119, 20,
     626  "1.c8966iabcf4de94ad15f9e83j407i3he7fch54h5jh0g5d74e06c057gg72a107didj8d1j8geibbfec5j36c3fgd5e12edjb9g10j7c9i03f33hi80ce0@7153",
     627  "1.0101110101100011110001001110100110011000100000001001000110111110011111100011111010011101011111101101010011110111110100e30915"},
     628  {93, 13,
     629  "2.c749cb562c3a758b1a21a650666a4c6c53c76ca58a1a75a0358c9ac3866887972b3551a03aa6c150856531258508@193",
     630  "1.10101111101001011010111101100100111110011111010110111101100100010011001001100011110100111110e715"},
     631  {145, 14,
     632  "1.c61614b64261d22c62cb9d16163ca4d144ac23351b708506b3b610b1b67b764ca974448d7a2c6515a6bc97503d4b2a530c75b2b677a464c6629c69b6c3d7860d7749b4b653c434d5@2050",
     633  "1.111111100001101111100011001111100010010000101000011110000001110100111001011010100001001010111111010001111101000110011000011101110110001001100101e7805"},
     634  {159, 23,
     635  "4.bj9l07l0215e7l6lf1dkf62i056l37jaa0gdih717656f1kk1a77883jf99jg31le43em76bmcg4lddl782ihkla0m392886d8lm67d6c3a1l4j12kg0l1k52ee77lmk0gech11g8jeei680k85bi460c7el17@-1539",
     636  "1.01010100110100100101100001011100000001100011110001001101000010000001000010000110000110010001110100001101011101101001001101101111001101101111101001010010010100e-6960"},
     637  {24, 25,
     638  "g.m749al09kflg5b42jnn4a7b@-2820",
     639  "1.01010010101011010111011e-13092"},
     640  {88, 18,
     641  "3.5ed0gad0bhhb7aa9ge2ad1dhcg6833f3e068936hghf23gd2aa69f13539f15hfce50aa64achfee49bfg7249g@-4058",
     642  "1.001000010110011011000101100000101111101001100011101101001111110111000010010110010001100e-16920"}
     643  };
     644  
     645  static void
     646  check_reftable (void)
     647  {
     648    int i, base;
     649    mpfr_t x, y;
     650    mpfr_prec_t p;
     651    char *s;
     652  
     653    mpfr_init2 (x, 200);
     654    mpfr_init2 (y, 200);
     655    for (i = 0 ; i < numberof (RefTable) ; i++)
     656      {
     657        base = RefTable[i].base;
     658        p    = RefTable[i].prec;
     659        mpfr_set_prec (x, p);
     660        mpfr_set_prec (y, p);
     661        mpfr_set_str_binary (x, RefTable[i].binstr);
     662        mpfr_strtofr (y, RefTable[i].str, &s, base, MPFR_RNDN);
     663        if (s == NULL || *s != 0)
     664          {
     665            printf ("strtofr didn't parse entire input for i=%d:\n"
     666                    " Str=%s", i, RefTable[i].str);
     667            exit (1);
     668          }
     669        if (mpfr_cmp (x, y))
     670          {
     671            printf ("Results differ between strtofr and set_binary for i=%d:\n"
     672                    " Set binary gives: ", i);
     673            mpfr_dump (x);
     674            printf (" strtofr    gives: ");
     675            mpfr_dump (y);
     676            printf (" setstr     gives: ");
     677            mpfr_set_str (x, RefTable[i].str, base, MPFR_RNDN);
     678            mpfr_dump (x);
     679            mpfr_set_prec (x, 2*p);
     680            mpfr_set_str (x, RefTable[i].str, base, MPFR_RNDN);
     681            printf (" setstr ++  gives: ");
     682            mpfr_dump (x);
     683            exit (1);
     684          }
     685      }
     686    mpfr_clear (y);
     687    mpfr_clear (x);
     688  }
     689  
     690  static void
     691  check_parse (void)
     692  {
     693    mpfr_t x;
     694    char *s;
     695    int res;
     696  
     697    mpfr_init (x);
     698  
     699    /* Invalid data */
     700    mpfr_set_si (x, -1, MPFR_RNDN);
     701    res = mpfr_strtofr (x, "  invalid", NULL, 10, MPFR_RNDN);
     702    if (MPFR_NOTZERO (x) || MPFR_IS_NEG (x))
     703      {
     704        printf ("Failed parsing '  invalid' (1)\n X=");
     705        mpfr_dump (x);
     706        exit (1);
     707      }
     708    MPFR_ASSERTN (res == 0);
     709    mpfr_set_si (x, -1, MPFR_RNDN);
     710    res = mpfr_strtofr (x, "  invalid", &s, 0, MPFR_RNDN);
     711    if (MPFR_NOTZERO (x) || MPFR_IS_NEG (x) || strcmp (s, "  invalid"))
     712      {
     713        printf ("Failed parsing '  invalid' (2)\n S=%s\n X=", s);
     714        mpfr_dump (x);
     715        exit (1);
     716      }
     717    MPFR_ASSERTN (res == 0);
     718    /* Check if it stops correctly */
     719    mpfr_strtofr (x, "15*x", &s, 10, MPFR_RNDN);
     720    if (mpfr_cmp_ui (x, 15) || strcmp (s, "*x"))
     721      {
     722        printf ("Failed parsing '15*x'\n S=%s\n X=", s);
     723        mpfr_dump (x);
     724        exit (1);
     725      }
     726    /* Check for leading spaces */
     727    mpfr_strtofr (x, "  1.5E-10 *x^2", &s, 10, MPFR_RNDN);
     728    if (mpfr_cmp_str1 (x, "1.5E-10") || strcmp (s, " *x^2"))
     729      {
     730        printf ("Failed parsing '1.5E-10*x^2'\n S=%s\n X=", s);
     731        mpfr_dump (x);
     732        exit (1);
     733      }
     734    /* Check for leading sign */
     735    mpfr_strtofr (x, "  +17.5E-42E ", &s, 10, MPFR_RNDN);
     736    if (mpfr_cmp_str1 (x, "17.5E-42") || strcmp (s, "E "))
     737      {
     738        printf ("Failed parsing '+17.5E-42E '\n S=%s\n X=", s);
     739        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
     740        exit (1);
     741      }
     742    mpfr_strtofr (x, "-17.5E+42E\n", &s, 10, MPFR_RNDN);
     743    if (mpfr_cmp_str1 (x, "-17.5E42") || strcmp (s, "E\n"))
     744      {
     745        printf ("Failed parsing '-17.5E+42\\n'\n S=%s\n X=", s);
     746        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
     747        exit (1);
     748      }
     749    /* P form */
     750    mpfr_strtofr (x, "0x42P17", &s, 16, MPFR_RNDN);
     751    if (mpfr_cmp_str (x, "8650752", 10, MPFR_RNDN) || *s != 0)
     752      {
     753        printf ("Failed parsing '0x42P17' (base = 16)\n S='%s'\n X=", s);
     754        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
     755        exit (1);
     756      }
     757    mpfr_strtofr (x, "-0X42p17", &s, 16, MPFR_RNDN);
     758    if (mpfr_cmp_str (x, "-8650752", 10, MPFR_RNDN) || *s != 0)
     759      {
     760        printf ("Failed parsing '-0x42p17' (base = 16)\n S='%s'\n X=", s);
     761        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
     762        exit (1);
     763      }
     764    mpfr_strtofr (x, "42p17", &s, 16, MPFR_RNDN);
     765    if (mpfr_cmp_str (x, "8650752", 10, MPFR_RNDN) || *s != 0)
     766      {
     767        printf ("Failed parsing '42p17' (base = 16)\n S='%s'\n X=", s);
     768        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
     769        exit (1);
     770      }
     771    mpfr_strtofr (x, "-42P17", &s, 16, MPFR_RNDN);
     772    if (mpfr_cmp_str (x, "-8650752", 10, MPFR_RNDN) || *s != 0)
     773      {
     774        printf ("Failed parsing '-42P17' (base = 16)\n S='%s'\n X=", s);
     775        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
     776        exit (1);
     777      }
     778    mpfr_strtofr (x, "0b1001P17", &s, 2, MPFR_RNDN);
     779    if (mpfr_cmp_str (x, "1179648", 10, MPFR_RNDN) || *s != 0)
     780      {
     781        printf ("Failed parsing '0b1001P17' (base = 2)\n S='%s'\n X=", s);
     782        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
     783        exit (1);
     784      }
     785    mpfr_strtofr (x, "-0B1001p17", &s, 2, MPFR_RNDN);
     786    if (mpfr_cmp_str (x, "-1179648", 10, MPFR_RNDN) || *s != 0)
     787      {
     788        printf ("Failed parsing '-0B1001p17' (base = 2)\n S='%s'\n X=", s);
     789        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
     790        exit (1);
     791      }
     792    mpfr_strtofr (x, "1001p17", &s, 2, MPFR_RNDN);
     793    if (mpfr_cmp_str (x, "1179648", 10, MPFR_RNDN) || *s != 0)
     794      {
     795        printf ("Failed parsing '1001p17' (base = 2)\n S='%s'\n X=", s);
     796        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
     797        exit (1);
     798      }
     799    mpfr_strtofr (x, "-1001P17", &s, 2, MPFR_RNDN);
     800    if (mpfr_cmp_str (x, "-1179648", 10, MPFR_RNDN) || *s != 0)
     801      {
     802        printf ("Failed parsing '-1001P17' (base = 2)\n S='%s'\n X=", s);
     803        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
     804        exit (1);
     805      }
     806    /* Check for auto-detection of the base */
     807    mpfr_strtofr (x, "+0x42P17", &s, 0, MPFR_RNDN);
     808    if (mpfr_cmp_str (x, "42P17", 16, MPFR_RNDN) || *s != 0)
     809      {
     810        printf ("Failed parsing '+0x42P17'\n S=%s\n X=", s);
     811        mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
     812        exit (1);
     813      }
     814    mpfr_strtofr (x, "-42E17", &s, 0, MPFR_RNDN);
     815    if (mpfr_cmp_str (x, "-42E17", 10, MPFR_RNDN) || *s != 0)
     816      {
     817        printf ("Failed parsing '-42E17'\n S=%s\n X=", s);
     818        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
     819        exit (1);
     820      }
     821    mpfr_strtofr (x, "-42P17", &s, 0, MPFR_RNDN);
     822    if (mpfr_cmp_str (x, "-42", 10, MPFR_RNDN) || strcmp (s, "P17"))
     823      {
     824        printf ("Failed parsing '-42P17' (base = 0)\n S='%s'\n X=", s);
     825        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
     826        exit (1);
     827      }
     828    mpfr_strtofr (x, " 0b0101.011@42", &s, 0, MPFR_RNDN);
     829    if (mpfr_cmp_str (x, "0101.011@42", 2, MPFR_RNDN) || *s != 0)
     830      {
     831        printf ("Failed parsing '0101.011@42'\n S=%s\n X=", s);
     832        mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n');
     833        exit (1);
     834      }
     835    mpfr_strtofr (x, " 0b0101.011P42", &s, 0, MPFR_RNDN);
     836    if (mpfr_cmp_str (x, "0101.011@42", 2, MPFR_RNDN) || *s != 0)
     837      {
     838        printf ("Failed parsing '0101.011@42'\n S=%s\n X=", s);
     839        mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n');
     840        exit (1);
     841      }
     842    mpfr_strtofr (x, "+0x42@17", &s, 0, MPFR_RNDN);
     843    if (mpfr_cmp_str (x, "4.2@18", 16, MPFR_RNDN) || *s != 0)
     844      {
     845        printf ("Failed parsing '+0x42P17'\n S=%s\n X=", s);
     846        mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
     847        exit (1);
     848      }
     849  
     850  
     851    /* Check for space inside the mantissa */
     852    mpfr_strtofr (x, "+0x4 2@17", &s, 0, MPFR_RNDN);
     853    if (mpfr_cmp_ui (x, 4) || strcmp(s," 2@17"))
     854      {
     855        printf ("Failed parsing '+0x4 2@17'\n S=%s\n X=", s);
     856        mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
     857        exit (1);
     858      }
     859    mpfr_strtofr (x, "+0x42 P17", &s, 0, MPFR_RNDN);
     860    if (mpfr_cmp_ui (x, 0x42) || strcmp(s," P17"))
     861      {
     862        printf ("Failed parsing '+0x42 P17'\n S=%s\n X=", s);
     863        mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
     864        exit (1);
     865      }
     866    /* Space between mantissa and exponent */
     867    mpfr_strtofr (x, " -0b0101P 17", &s, 0, MPFR_RNDN);
     868    if (mpfr_cmp_si (x, -5) || strcmp(s,"P 17"))
     869      {
     870        printf ("Failed parsing '-0b0101P 17'\n S=%s\n X=", s);
     871        mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n');
     872        exit (1);
     873      }
     874    /* Check for Invalid exponent. */
     875    mpfr_strtofr (x, " -0b0101PF17", &s, 0, MPFR_RNDN);
     876    if (mpfr_cmp_si (x, -5) || strcmp(s,"PF17"))
     877      {
     878        printf ("Failed parsing '-0b0101PF17'\n S=%s\n X=", s);
     879        mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n');
     880        exit (1);
     881      }
     882    /* At least one digit in the mantissa. */
     883    mpfr_strtofr (x, " .E10", &s, 0, MPFR_RNDN);
     884    if (strcmp(s," .E10"))
     885      {
     886        printf ("Failed parsing ' .E10'\n S=%s\n X=", s);
     887        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
     888        exit (1);
     889      }
     890    /* Check 2 '.': 2.3.4   */
     891    mpfr_strtofr (x, "-1.2.3E4", &s, 0, MPFR_RNDN);
     892    if (mpfr_cmp_str1 (x, "-1.2") || strcmp(s,".3E4"))
     893      {
     894        printf ("Failed parsing '-1.2.3E4'\n S=%s\n X=", s);
     895        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
     896        exit (1);
     897      }
     898    /* Check for 0x and 0b */
     899    mpfr_strtofr (x, "  0xG", &s, 0, MPFR_RNDN);
     900    if (mpfr_cmp_ui (x, 0) || strcmp(s,"xG"))
     901      {
     902        printf ("Failed parsing '  0xG'\n S=%s\n X=", s);
     903        mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
     904        exit (1);
     905      }
     906    mpfr_strtofr (x, "  0b2", &s, 0, MPFR_RNDN);
     907    if (mpfr_cmp_ui (x, 0) || strcmp(s,"b2"))
     908      {
     909        printf ("Failed parsing '  0b2'\n S=%s\n X=", s);
     910        mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n');
     911        exit (1);
     912      }
     913    mpfr_strtofr (x, "-0x.23@2Z33", &s, 0, MPFR_RNDN);
     914    if (mpfr_cmp_si (x, -0x23) || strcmp(s,"Z33"))
     915      {
     916        printf ("Failed parsing '-0x.23@2Z33'\n S=%s\n X=", s);
     917        mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
     918        exit (1);
     919      }
     920    mpfr_strtofr (x, "  0x", &s, 0, MPFR_RNDN);
     921    if (mpfr_cmp_ui (x, 0) || strcmp(s,"x"))
     922      {
     923        printf ("Failed parsing '  0x'\n S=%s\n X=", s);
     924        mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
     925        exit (1);
     926      }
     927  
     928    mpfr_clear (x);
     929  }
     930  
     931  static void
     932  check_overflow (void)
     933  {
     934    mpfr_t x;
     935    char *s;
     936  
     937    mpfr_init (x);
     938  
     939    /* Huge overflow */
     940    mpfr_strtofr (x, "123456789E2147483646", &s, 0, MPFR_RNDN);
     941    if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x) )
     942      {
     943        printf ("Check overflow failed (1) with:\n s=%s\n x=", s);
     944        mpfr_dump (x);
     945        exit (1);
     946      }
     947    mpfr_strtofr (x, "123456789E9223372036854775807", &s, 0, MPFR_RNDN);
     948    if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x) )
     949      {
     950        printf ("Check overflow failed (2) with:\n s='%s'\n x=", s);
     951        mpfr_dump (x);
     952  #if defined(__GNUC__)
     953        printf ("This failure is triggered by GCC bug 86554:\n"
     954                "  https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86554\n"
     955                "  https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87276 "
     956                "(about this test)\nWorkaround: disable code hoisting "
     957                "with -fno-code-hoisting in CFLAGS.\n");
     958        /* Note: In Debian, this error is obtained with gcc-snapshot from
     959           20180908-1 to 20181127-1. With gcc-snapshot from 20181209-1 to
     960           20190102-1 (at least), the MPFR build no longer seems affected
     961           in general, but using --with-gmp-build=... together with
     962           --enable-assert still triggers this failure. This bug has been
     963           fixed in the GCC trunk rev 267725, thus the future gcc-snapshot
     964           versions should no longer have this bug. */
     965  #endif
     966        exit (1);
     967      }
     968    mpfr_strtofr (x, "123456789E170141183460469231731687303715884105728",
     969                  &s, 0, MPFR_RNDN);
     970    if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x) )
     971      {
     972        printf ("Check overflow failed (3) with:\n s=%s\n x=", s);
     973        mpfr_dump (x);
     974        exit (1);
     975      }
     976  
     977    /* Limit overflow */
     978    mpfr_strtofr (x, "12E2147483646", &s, 0, MPFR_RNDN);
     979    if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x) )
     980      {
     981        printf ("Check overflow failed (4) with:\n s=%s\n x=", s);
     982        mpfr_dump (x);
     983        exit (1);
     984      }
     985    mpfr_strtofr (x, "12E2147483645", &s, 0, MPFR_RNDN);
     986    if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x))
     987      {
     988        printf ("Check overflow failed (5) with:\n s=%s\n x=", s);
     989        mpfr_dump (x);
     990        exit (1);
     991      }
     992    mpfr_strtofr (x, "0123456789ABCDEF@2147483640", &s, 16, MPFR_RNDN);
     993    if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x))
     994      {
     995        printf ("Check overflow failed (6) with:\n s=%s\n x=", s);
     996        mpfr_dump (x);
     997        exit (1);
     998      }
     999    mpfr_strtofr (x, "0123456789ABCDEF@540000000", &s, 16, MPFR_RNDN);
    1000    if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x))
    1001      {
    1002        printf ("Check overflow failed (7) with:\n s=%s\n x=", s);
    1003        mpfr_dump (x);
    1004        exit (1);
    1005      }
    1006    mpfr_strtofr (x, "1@2305843009213693951", &s, 16, MPFR_RNDN);
    1007    if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x))
    1008      {
    1009        printf ("Check overflow failed (8) with:\n s=%s\n x=", s);
    1010        mpfr_dump (x);
    1011        exit (1);
    1012      }
    1013    mpfr_strtofr (x, "1@2305843009213693951", &s, 17, MPFR_RNDN);
    1014    if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x))
    1015      {
    1016        printf ("Check overflow failed (9) with:\n s=%s\n x=", s);
    1017        mpfr_dump (x);
    1018        exit (1);
    1019      }
    1020  
    1021    /* Check underflow */
    1022    mpfr_strtofr (x, "123456789E-2147483646", &s, 0, MPFR_RNDN);
    1023    if (s[0] != 0 || !MPFR_IS_ZERO (x) || !MPFR_IS_POS (x) )
    1024      {
    1025        printf ("Check underflow failed (1) with:\n s=%s\n x=", s);
    1026        mpfr_dump (x);
    1027        exit (1);
    1028      }
    1029    mpfr_strtofr (x, "123456789E-9223372036854775807", &s, 0, MPFR_RNDN);
    1030    if (s[0] != 0 || !MPFR_IS_ZERO (x) || !MPFR_IS_POS (x) )
    1031      {
    1032        printf ("Check underflow failed (2) with:\n s='%s'\n x=", s);
    1033        mpfr_dump (x);
    1034        exit (1);
    1035      }
    1036    mpfr_strtofr (x, "-123456789E-170141183460469231731687303715884105728",
    1037                  &s, 0, MPFR_RNDN);
    1038    if (s[0] != 0 || !MPFR_IS_ZERO (x) || !MPFR_IS_NEG (x) )
    1039      {
    1040        printf ("Check underflow failed (3) with:\n s=%s\n x=", s);
    1041        mpfr_dump (x);
    1042        exit (1);
    1043      }
    1044    mpfr_strtofr (x, "0123456789ABCDEF@-540000000", &s, 16, MPFR_RNDN);
    1045    if (s[0] != 0 || !MPFR_IS_ZERO (x) || !MPFR_IS_POS (x))
    1046      {
    1047        printf ("Check overflow failed (7) with:\n s=%s\n x=", s);
    1048        mpfr_dump (x);
    1049        exit (1);
    1050      }
    1051    mpfr_strtofr (x, "1@-2305843009213693952", &s, 16, MPFR_RNDN);
    1052    if (s[0] != 0 || !MPFR_IS_ZERO (x) || !MPFR_IS_POS (x) )
    1053      {
    1054        printf ("Check underflow failed (8) with:\n s='%s'\n x=", s);
    1055        mpfr_dump (x);
    1056        exit (1);
    1057      }
    1058  
    1059    mpfr_clear (x);
    1060  }
    1061  
    1062  static void
    1063  check_retval (void)
    1064  {
    1065    mpfr_t x;
    1066    int res;
    1067  
    1068    mpfr_init2 (x, 10);
    1069  
    1070    res = mpfr_strtofr (x, "01011000111", NULL, 2, MPFR_RNDN);
    1071    MPFR_ASSERTN (res == 0);
    1072    res = mpfr_strtofr (x, "11011000111", NULL, 2, MPFR_RNDN);
    1073    MPFR_ASSERTN (res > 0);
    1074    res = mpfr_strtofr (x, "110110001101", NULL, 2, MPFR_RNDN);
    1075    MPFR_ASSERTN (res < 0);
    1076  
    1077    mpfr_clear (x);
    1078  }
    1079  
    1080  /* Bug found by Christoph Lauter (in mpfr_set_str). */
    1081  static struct bug20081025_test {
    1082    mpfr_rnd_t rnd;
    1083    int inexact;
    1084    const char *str;
    1085    const char *binstr;
    1086  } Bug20081028Table[] = {
    1087    {MPFR_RNDN, -1, "1.00000000000000000006", "1"},
    1088    {MPFR_RNDZ, -1, "1.00000000000000000006", "1"},
    1089    {MPFR_RNDU, +1, "1.00000000000000000006",
    1090     "10000000000000000000000000000001e-31"},
    1091    {MPFR_RNDD, -1, "1.00000000000000000006", "1"},
    1092  
    1093  
    1094    {MPFR_RNDN, +1, "-1.00000000000000000006", "-1"},
    1095    {MPFR_RNDZ, +1, "-1.00000000000000000006", "-1"},
    1096    {MPFR_RNDU, +1, "-1.00000000000000000006", "-1"},
    1097    {MPFR_RNDD, -1, "-1.00000000000000000006",
    1098     "-10000000000000000000000000000001e-31"},
    1099  
    1100    {MPFR_RNDN, +1, "0.999999999999999999999999999999999999999999999", "1"},
    1101    {MPFR_RNDZ, -1, "0.999999999999999999999999999999999999999999999",
    1102     "11111111111111111111111111111111e-32"},
    1103    {MPFR_RNDU, +1, "0.999999999999999999999999999999999999999999999", "1"},
    1104    {MPFR_RNDD, -1, "0.999999999999999999999999999999999999999999999",
    1105     "11111111111111111111111111111111e-32"},
    1106  
    1107    {MPFR_RNDN, -1, "-0.999999999999999999999999999999999999999999999", "-1"},
    1108    {MPFR_RNDZ, +1, "-0.999999999999999999999999999999999999999999999",
    1109     "-11111111111111111111111111111111e-32"},
    1110    {MPFR_RNDU, +1, "-0.999999999999999999999999999999999999999999999",
    1111     "-11111111111111111111111111111111e-32"},
    1112    {MPFR_RNDD, -1, "-0.999999999999999999999999999999999999999999999", "-1"}
    1113  };
    1114  
    1115  static void
    1116  bug20081028 (void)
    1117  {
    1118    int i;
    1119    int inexact, res;
    1120    mpfr_rnd_t rnd;
    1121    mpfr_t x, y;
    1122    char *s;
    1123  
    1124    mpfr_init2 (x, 32);
    1125    mpfr_init2 (y, 32);
    1126    for (i = 0 ; i < numberof (Bug20081028Table) ; i++)
    1127      {
    1128        rnd     = Bug20081028Table[i].rnd;
    1129        inexact = Bug20081028Table[i].inexact;
    1130        mpfr_set_str_binary (x, Bug20081028Table[i].binstr);
    1131        res = mpfr_strtofr (y, Bug20081028Table[i].str, &s, 10, rnd);
    1132        if (s == NULL || *s != 0)
    1133          {
    1134            printf ("Error in Bug20081028: strtofr didn't parse entire input\n"
    1135                    "for (i=%d) Str=\"%s\"", i, Bug20081028Table[i].str);
    1136            exit (1);
    1137          }
    1138        if (! SAME_SIGN (res, inexact))
    1139          {
    1140            printf ("Error in Bug20081028: expected %s ternary value, "
    1141                    "got %d\nfor (i=%d) Rnd=%s Str=\"%s\"\n Set binary gives: ",
    1142                    inexact > 0 ? "positive" : "negative",
    1143                    res, i, mpfr_print_rnd_mode(rnd), Bug20081028Table[i].str);
    1144            mpfr_dump (x);
    1145            printf (" strtofr    gives: ");
    1146            mpfr_dump (y);
    1147            exit (1);
    1148          }
    1149        if (mpfr_cmp (x, y))
    1150          {
    1151            printf ("Error in Bug20081028: Results differ between strtofr and "
    1152                    "set_binary\nfor (i=%d) Rnd=%s Str=\"%s\"\n"
    1153                    " Set binary gives: ",
    1154                    i, mpfr_print_rnd_mode(rnd), Bug20081028Table[i].str);
    1155            mpfr_dump (x);
    1156            printf (" strtofr    gives: ");
    1157            mpfr_dump (y);
    1158            exit (1);
    1159          }
    1160      }
    1161    mpfr_clear (y);
    1162    mpfr_clear (x);
    1163  }
    1164  
    1165  /* check that 1.23e is correctly parsed, cf
    1166     https://gmplib.org/list-archives/gmp-bugs/2010-March/001898.html */
    1167  static void
    1168  test20100310 (void)
    1169  {
    1170    mpfr_t x, y;
    1171    char str[] = "1.23e", *endptr;
    1172  
    1173    mpfr_init2 (x, 53);
    1174    mpfr_init2 (y, 53);
    1175    mpfr_strtofr (x, str, &endptr, 10, MPFR_RNDN);
    1176    mpfr_strtofr (y, "1.23", NULL, 10, MPFR_RNDN);
    1177    if (mpfr_cmp (x, y) != 0)
    1178      {
    1179        printf ("x <> y in test20100310\n");
    1180        exit (1);
    1181      }
    1182    if (endptr != str + 4) /* strtofr should take into account '1.23',
    1183                              not '1.23e' */
    1184      {
    1185        printf ("endptr <> str + 4 in test20100310\n");
    1186        exit (1);
    1187      }
    1188    mpfr_clear (x);
    1189    mpfr_clear (y);
    1190  }
    1191  
    1192  /* From a bug reported by Joseph S. Myers
    1193     https://sympa.inria.fr/sympa/arc/mpfr/2012-08/msg00005.html */
    1194  static void
    1195  bug20120814 (void)
    1196  {
    1197    mpfr_exp_t emin = -30, e;
    1198    mpfr_t x, y;
    1199    int r;
    1200    char s[64], *p;
    1201  
    1202    mpfr_init2 (x, 2);
    1203    mpfr_set_ui_2exp (x, 3, emin - 2, MPFR_RNDN);
    1204    mpfr_get_str (s + 1, &e, 10, 19, x, MPFR_RNDD);
    1205    s[0] = s[1];
    1206    s[1] = '.';
    1207    for (p = s; *p != 0; p++) ;
    1208    *p = 'e';
    1209    sprintf (p + 1, "%d", (int) e - 1);
    1210  
    1211    mpfr_init2 (y, 4);
    1212    r = mpfr_strtofr (y, s, NULL, 0, MPFR_RNDN);
    1213    if (r <= 0 || ! mpfr_equal_p (x, y))
    1214      {
    1215        printf ("Error in bug20120814\n");
    1216        printf ("mpfr_strtofr failed on string \"%s\"\n", s);
    1217        printf ("Expected inex > 0 and y = 0.1100E%d\n", (int) emin);
    1218        printf ("Got inex = %-6d and y = ", r);
    1219        mpfr_dump (y);
    1220        exit (1);
    1221      }
    1222  
    1223    mpfr_clear (x);
    1224    mpfr_clear (y);
    1225  }
    1226  
    1227  static void
    1228  bug20120829 (void)
    1229  {
    1230    mpfr_t x1, x2, e;
    1231    int inex1, inex2, i, r;
    1232    char s[48] = "1e-1";
    1233  
    1234    mpfr_init2 (e, 128);
    1235    mpfr_inits2 (4, x1, x2, (mpfr_ptr) 0);
    1236  
    1237    inex1 = mpfr_set_si (e, -1, MPFR_RNDN);
    1238    MPFR_ASSERTN (inex1 == 0);
    1239  
    1240    for (i = 1; i <= sizeof(s) - 5; i++)
    1241      {
    1242        s[3+i] = '0';
    1243        s[4+i] = 0;
    1244        inex1 = mpfr_mul_ui (e, e, 10, MPFR_RNDN);
    1245        MPFR_ASSERTN (inex1 == 0);
    1246        RND_LOOP_NO_RNDF (r)
    1247          {
    1248            mpfr_rnd_t rnd = (mpfr_rnd_t) r;
    1249  
    1250            inex1 = mpfr_exp10 (x1, e, rnd);
    1251            inex1 = VSIGN (inex1);
    1252            inex2 = mpfr_strtofr (x2, s, NULL, 0, rnd);
    1253            inex2 = VSIGN (inex2);
    1254            /* On 32-bit machines, for i = 7, r8389, r8391 and r8394 do:
    1255               strtofr.c:...: MPFR assertion failed: cy == 0
    1256               r8396 is OK.
    1257               On 64-bit machines, for i = 15,
    1258               r8389 does: strtofr.c:678: MPFR assertion failed: err < (64 - 0)
    1259               r8391 does: strtofr.c:680: MPFR assertion failed: h < ysize
    1260               r8394 and r8396 are OK.
    1261            */
    1262            if (! mpfr_equal_p (x1, x2) || inex1 != inex2)
    1263              {
    1264                printf ("Error in bug20120829 for i = %d, rnd = %s\n",
    1265                        i, mpfr_print_rnd_mode (rnd));
    1266                printf ("Expected inex = %d, x = ", inex1);
    1267                mpfr_dump (x1);
    1268                printf ("Got      inex = %d, x = ", inex2);
    1269                mpfr_dump (x2);
    1270                exit (1);
    1271              }
    1272          }
    1273      }
    1274  
    1275    mpfr_clears (e, x1, x2, (mpfr_ptr) 0);
    1276  }
    1277  
    1278  /* https://sympa.inria.fr/sympa/arc/mpfr/2016-12/msg00043.html
    1279     mpfr_strtofr can return an incorrect ternary value.
    1280     Note: As a consequence, the value can also be incorrect if the current
    1281     exponent range is not the maximum one (since the ternary value is used
    1282     to resolve double rounding in mpfr_check_range); this can happen only
    1283     if the value is a midpoint between 0 and the minimum positive number
    1284     or the opposite. */
    1285  static void
    1286  bug20161217 (void)
    1287  {
    1288    mpfr_t fp, z;
    1289    static const char * num = "0.1387778780781445675529539585113525390625e31";
    1290    /* The above number is 5^47/2^9. */
    1291    int inex;
    1292  
    1293    mpfr_init2 (fp, 110);
    1294    mpfr_init2 (z, 110);
    1295  
    1296    inex = mpfr_strtofr (fp, num, NULL, 10, MPFR_RNDN);
    1297    MPFR_ASSERTN(inex == 0);
    1298    mpfr_set_str_binary (z, "10001100001000010011110110011101101001010000001011011110010001010100010100100110111101000010001011001100001101E-9");
    1299    MPFR_ASSERTN(mpfr_equal_p (fp, z));
    1300  
    1301    /* try with 109 bits */
    1302    mpfr_set_prec (fp, 109);
    1303    inex = mpfr_strtofr (fp, num, NULL, 10, MPFR_RNDN);
    1304    MPFR_ASSERTN(inex < 0);
    1305    mpfr_set_str_binary (z, "10001100001000010011110110011101101001010000001011011110010001010100010100100110111101000010001011001100001100E-9");
    1306    MPFR_ASSERTN(mpfr_equal_p (fp, z));
    1307  
    1308    mpfr_clear (fp);
    1309    mpfr_clear (z);
    1310  }
    1311  
    1312  /* check bug in MPFR 3.1.5 is fixed: cf
    1313     https://sympa.inria.fr/sympa/arc/mpfr/2017-03/msg00009.html
    1314     Note: same bug as bug20161217. See also the comments of bug20161217;
    1315     here, this is a case where the value is incorrect. */
    1316  static void
    1317  bug20170308 (void)
    1318  {
    1319    mpfr_exp_t emin;
    1320     /* the following is slightly larger than 2^-1075, thus should be rounded
    1321        to 0.5*2^-1074, with ternary value < 0 */
    1322    char str[] = "2.47032822920623272089E-324";
    1323    mpfr_t z;
    1324    int inex;
    1325  
    1326    emin = mpfr_get_emin ();
    1327    mpfr_init2 (z, 53);
    1328    set_emin (-1073);
    1329    /* with emin = -1073, the smallest positive number is 0.5*2^emin = 2^(-1074),
    1330       thus str should be rounded to 2^(-1074) with inex > 0 */
    1331    inex = mpfr_strtofr (z, str, NULL, 10, MPFR_RNDN);
    1332    MPFR_ASSERTN(inex > 0 && mpfr_cmp_ui_2exp (z, 1, -1074) == 0);
    1333    set_emin (-1074);
    1334    /* with emin = -1074, str should be rounded to 2^(-1075) with inex < 0 */
    1335    inex = mpfr_strtofr (z, str, NULL, 10, MPFR_RNDN);
    1336    MPFR_ASSERTN(inex < 0 && mpfr_cmp_ui_2exp (z, 1, -1075) == 0);
    1337    mpfr_clear (z);
    1338    set_emin (emin);
    1339  }
    1340  
    1341  /* r13299 fails with 8-bit limbs (micro-gmp/8). */
    1342  static void
    1343  bug20181127 (void)
    1344  {
    1345    char s[] = "9.Z6nrLVSMG1bDcCF2ONJdX@-183295525";  /* base 58 */
    1346    mpfr_t x, y;
    1347  
    1348    mpfr_inits2 (6, x, y, (mpfr_ptr) 0);
    1349    mpfr_set_ui_2exp (x, 5, -1073741701, MPFR_RNDN);
    1350    mpfr_strtofr (y, s, NULL, 58, MPFR_RNDZ);
    1351    if (! mpfr_equal_p (x, y))
    1352      {
    1353        printf ("Error in bug20181127 on %s (base 58)\n", s);
    1354        printf ("Expected x = ");
    1355        mpfr_dump (x);
    1356        printf ("Got      y = ");
    1357        mpfr_dump (y);
    1358        printf ("*Note* In base 58, x ~= ");
    1359        mpfr_out_str (stdout, 58, 8, x, MPFR_RNDN);
    1360        printf ("\n");
    1361        exit (1);
    1362      }
    1363    mpfr_clears (x, y, (mpfr_ptr) 0);
    1364  }
    1365  
    1366  /* Bug reported by Michael Jones (case i = 0 below)
    1367       https://sympa.inria.fr/sympa/arc/mpfr/2023-06/msg00000.html
    1368     This yields an integer overflow -LONG_MIN. The result might still
    1369     be correct, but a runtime error is obtained with an UB sanitizer:
    1370       strtofr.c:745:11: runtime error: negation of -9223372036854775808 [...]
    1371     Details after an analysis:
    1372     With GCC 4.9.4 and tcc, one gets an assertion failure:
    1373       mpn_exp.c:94: MPFR assertion failed: e > 0
    1374     And if all assertions are disabled with
    1375       ./configure --enable-assert=none CC=gcc-4.9
    1376     one gets an incorrect result:
    1377       Error in bug20230606 for i = 0
    1378       Expected x = 0
    1379       Got      x = 0.11001100110011001E-3
    1380     This issue is not visible with GCC 8.4.0 and later, even with -O0,
    1381     because GCC now transforms "-X >= 0" to "X <= 0" (which is valid
    1382     under the ISO C rules). Note that such an optimization generally
    1383     makes buggy code (which assumes "wrapping") fail; here, it makes
    1384     the bug invisible!
    1385  
    1386     Case i = 1 should be identical.
    1387  
    1388     Case i = 2 shows another bug (probably with all compilers):
    1389       Error in bug20230606 for i = 2
    1390       Expected x = 0
    1391       Got      x = 0.11111111111111111E1073741823
    1392     or with an UB sanitizer:
    1393       strtofr.c:428:19: runtime error: signed integer overflow: [...]
    1394     This is the bug mentioned at
    1395       https://sympa.inria.fr/sympa/arc/mpfr/2023-06/msg00001.html
    1396  */
    1397  static void
    1398  bug20230606 (void)
    1399  {
    1400    const char *const s[] = {
    1401      "0.1E-99999999999999999999",
    1402      ".1E-99999999999999999999",
    1403      ".01E-99999999999999999999" };
    1404    mpfr_t x;
    1405    int i;
    1406  
    1407    mpfr_init2 (x, 17);
    1408    for (i = 0; i < numberof (s); i++)
    1409      {
    1410        mpfr_strtofr (x, s[i], NULL, 10, MPFR_RNDZ);
    1411        if (!mpfr_zero_p (x) || mpfr_signbit (x) != 0)
    1412          {
    1413            printf ("Error in bug20230606 for i = %d\n", i);
    1414            printf ("Expected x = 0\n");
    1415            printf ("Got      x = ");
    1416            mpfr_dump (x);
    1417            exit (1);
    1418          }
    1419      }
    1420    mpfr_clear (x);
    1421  }
    1422  
    1423  static void
    1424  coverage (void)
    1425  {
    1426  #if _MPFR_EXP_FORMAT >= 3 && _MPFR_PREC_FORMAT == 3 && MPFR_PREC_BITS == 64
    1427    char str3[] = "1@-2112009130072406892";
    1428    char str31[] = "1@-511170973314085831";
    1429    mpfr_t x;
    1430    int inex;
    1431    mpfr_exp_t emin;
    1432  
    1433    /* exercise assertion cy == 0 around line 698 of strtofr.c */
    1434    emin = mpfr_get_emin ();
    1435    set_emin (mpfr_get_emin_min ());
    1436    /* emin = -4611686018427387903 on a 64-bit machine */
    1437    mpfr_init2 (x, 1);
    1438    inex = mpfr_strtofr (x, str3, NULL, 3, MPFR_RNDN);
    1439    /* 3^-2112009130072406892 is slightly larger than (2^64)^-52303988630398057
    1440       thus we should get inex < 0 */
    1441    MPFR_ASSERTN(inex < 0);
    1442    MPFR_ASSERTN(mpfr_cmp_ui_2exp (x, 1, -52303988630398057 * 64) == 0);
    1443    inex = mpfr_strtofr (x, str31, NULL, 31, MPFR_RNDN);
    1444    /* 31^-511170973314085831 is slightly smaller than (2^64)^-39569396093273623
    1445       thus we should get inex > 0 */
    1446    MPFR_ASSERTN(inex > 0);
    1447    MPFR_ASSERTN(mpfr_cmp_ui_2exp (x, 1, -39569396093273623 * 64) == 0);
    1448    mpfr_clear (x);
    1449    set_emin (emin);
    1450  #endif
    1451  }
    1452  
    1453  #define BSIZE 512
    1454  
    1455  static void
    1456  random_tests (void)
    1457  {
    1458    char s0[BSIZE], s1[BSIZE], s2[BSIZE+64];
    1459    mpfr_t x0, x1, x2;
    1460    int prec, i;
    1461  
    1462    for (prec = MPFR_PREC_MIN; prec < 300; prec++)
    1463      {
    1464        mpfr_inits2 (prec, x0, x1, x2, (mpfr_ptr) 0);
    1465  
    1466        for (i = 0; i < 20; i++)
    1467          {
    1468            const char *num_to_text;
    1469            mpfr_exp_t e0, e1;
    1470            int base, j, k, neg;
    1471            int noteq = 0;
    1472            char d;
    1473  
    1474            /* We want the same exponent for x0 and its successor x1.
    1475               This is not possible for precision 1 in base 2. */
    1476            do
    1477              base = 2 + (randlimb () % 61);
    1478            while (prec == 1 && base == 2);
    1479  
    1480            num_to_text = base <= 36 ? num_to_text36 : num_to_text62;
    1481  
    1482            do
    1483              {
    1484                /* Let's consider only positive numbers. We should test
    1485                   negative numbers, but they should be built later, just
    1486                   for the test itself. */
    1487                tests_default_random (x0, 0,
    1488                                      mpfr_get_emin (), mpfr_get_emax (), 1);
    1489                mpfr_set (x1, x0, MPFR_RNDN);
    1490                mpfr_nextabove (x1);
    1491                mpfr_get_str (s0, &e0, base, BSIZE - 1, x0, MPFR_RNDU);
    1492                mpfr_get_str (s1, &e1, base, BSIZE - 1, x1, MPFR_RNDD);
    1493              }
    1494            while (! (mpfr_regular_p (x0) && mpfr_regular_p (x1) && e0 == e1));
    1495  
    1496            /* 0 < x0 <= (s0,e) <= (s1,e) <= x1 with e = e0 = e1.
    1497               Let's build a string s2 randomly formed by:
    1498               - the common prefix of s0 and s1;
    1499               - some of the following digits of s0 (possibly none);
    1500               - the next digit of s0 + 1;
    1501               - some of the following digits of s1 (possibly none).
    1502               Then 0 < x0 <= (s0,e) < (s2,e) <= (s1,e) <= x1, and with
    1503               a very high probability that (s2,e) < (s1,e); noteq is
    1504               set to true in this case.
    1505               For instance, if:
    1506                 s0 = 123456789
    1507                 s1 = 124012345
    1508               one can have, e.g.:
    1509                 s2 = 12345734
    1510                 s2 = 123556789
    1511                 s2 = 124
    1512                 s2 = 124012
    1513               s2 is not taken completely randomly between s0 and s1, but it
    1514               will be built rather easily, and with the randomness of x0,
    1515               we should cover all cases, with s2 very close to s0, s2 very
    1516               close to s1, or not too close to either. */
    1517  
    1518            neg = RAND_BOOL ();
    1519            s2[0] = neg ? '-' : '+';
    1520            s2[1] = '.';
    1521  
    1522            for (j = 0;
    1523                 MPFR_ASSERTN (s0[j] != 0 && s1[j] != 0), s0[j] == s1[j];
    1524                 j++)
    1525              s2[j+2] = s0[j];
    1526  
    1527            /* k is the position of the first differing digit. */
    1528            k = j;
    1529  
    1530            while (j < BSIZE - 2 && randlimb () % 8 != 0)
    1531              {
    1532                MPFR_ASSERTN (s0[j] != 0);
    1533                s2[j+2] = s0[j];
    1534                j++;
    1535              }
    1536  
    1537            MPFR_ASSERTN (s0[j] != 0);
    1538            /* We will increment the next digit. Thus while s0[j] is the
    1539               maximum digit, go back until this is no longer the case
    1540               (the first digit after the common prefix cannot be the
    1541               maximum digit, so that we will stop early enough). */
    1542            while ((d = s0[j]) == num_to_text[base - 1])
    1543              j--;
    1544            noteq = j != k;
    1545            s2[j+2] = d = *(strchr (num_to_text, d) + 1);
    1546            if (d != s1[j])
    1547              noteq = 1;
    1548            j++;
    1549  
    1550            while (j < BSIZE - 1 && randlimb () % 8 != 0)
    1551              {
    1552                MPFR_ASSERTN (s1[j] != 0);
    1553                s2[j+2] = s1[j];
    1554                j++;
    1555              }
    1556  
    1557            sprintf (s2 + (j+2), "@%" MPFR_EXP_FSPEC "d", (mpfr_eexp_t) e0);
    1558  
    1559            while (noteq == 0 && j < BSIZE - 1)
    1560              {
    1561                if (s1[j] != '0')
    1562                  noteq = 1;
    1563                j++;
    1564              }
    1565  
    1566            if (neg)
    1567              {
    1568                mpfr_neg (x0, x0, MPFR_RNDN);
    1569                mpfr_neg (x1, x1, MPFR_RNDN);
    1570              }
    1571  
    1572            if (noteq)
    1573              {
    1574                mpfr_strtofr (x2, s2, NULL, base, MPFR_RNDZ);
    1575                if (! mpfr_equal_p (x2, x0))
    1576                  {
    1577                    printf ("Error in random_tests for prec=%d i=%d base=%d\n",
    1578                            prec, i, base);
    1579                    printf ("s0 = %s\ns1 = %s\ns2 = %s\n", s0, s1, s2);
    1580                    printf ("x0 = ");
    1581                    mpfr_dump (x0);
    1582                    printf ("x2 = ");
    1583                    mpfr_dump (x2);
    1584                    exit (1);
    1585                  }
    1586              }
    1587  
    1588            mpfr_strtofr (x2, s2, NULL, base, MPFR_RNDA);
    1589            if (! mpfr_equal_p (x2, x1))
    1590              {
    1591                printf ("Error in random_tests for prec=%d i=%d base=%d\n",
    1592                        prec, i, base);
    1593                printf ("s0 = %s\ns1 = %s\ns2 = %s\n", s0, s1, s2);
    1594                printf ("x1 = ");
    1595                mpfr_dump (x1);
    1596                printf ("x2 = ");
    1597                mpfr_dump (x2);
    1598                exit (1);
    1599              }
    1600          }
    1601        mpfr_clears (x0, x1, x2, (mpfr_ptr) 0);
    1602      }
    1603  }
    1604  
    1605  int
    1606  main (int argc, char *argv[])
    1607  {
    1608    tests_start_mpfr ();
    1609  
    1610    coverage ();
    1611    check_special();
    1612    check_reftable ();
    1613    check_parse ();
    1614    check_overflow ();
    1615    check_retval ();
    1616    bug20081028 ();
    1617    test20100310 ();
    1618    bug20120814 ();
    1619    bug20120829 ();
    1620    bug20161217 ();
    1621    bug20170308 ();
    1622    bug20181127 ();
    1623    bug20230606 ();
    1624    random_tests ();
    1625  
    1626    tests_end_mpfr ();
    1627    return 0;
    1628  }