/* Test file for mpfr_set_str. Copyright 2004-2021 Free Software Foundation, Inc. Contributed by the AriC and Caramba projects, INRIA. This file is part of the GNU MPFR Library. The GNU MPFR Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. The GNU MPFR Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "mpfr-test.h" /* The implicit \0 is useless, but we do not write num_to_text[62] otherwise g++ complains. */ static const char num_to_text36[] = "0123456789abcdefghijklmnopqrstuvwxyz"; static const char num_to_text62[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"; static void check_special (void) { mpfr_t x, y; int i, res; char *s; mpfr_init (x); mpfr_init (y); /* Check dummy case */ res = mpfr_strtofr (x, "1234567.89E1", NULL, 10, MPFR_RNDN); mpfr_set_str (y, "1234567.89E1", 10, MPFR_RNDN); if (mpfr_cmp (x, y)) { printf ("Results differ between strtofr and set_str.\n" " set_str gives: "); mpfr_dump (y); printf (" strtofr gives: "); mpfr_dump (x); exit (1); } /* Check NAN */ mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */ res = mpfr_strtofr (x, "NaN", &s, 10, MPFR_RNDN); if (res != 0 || !mpfr_nan_p (x) || *s != 0) { printf ("Error for setting NAN (1)\n"); exit (1); } mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */ res = mpfr_strtofr (x, "+NaN", &s, 10, MPFR_RNDN); if (res != 0 || !mpfr_nan_p (x) || *s != 0) { printf ("Error for setting +NAN (1)\n"); exit (1); } mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */ res = mpfr_strtofr (x, " -NaN", &s, 10, MPFR_RNDN); if (res != 0 || !mpfr_nan_p (x) || *s != 0) { printf ("Error for setting -NAN (1)\n"); exit (1); } mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */ res = mpfr_strtofr (x, "@nAn@xx", &s, 16, MPFR_RNDN); if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "xx") ) { printf ("Error for setting NAN (2)\n"); exit (1); } mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */ res = mpfr_strtofr (x, "NAN(abcdEDF__1256)Hello", &s, 10, MPFR_RNDN); if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "Hello") ) { printf ("Error for setting NAN (3)\n"); exit (1); } mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */ res = mpfr_strtofr (x, "NAN(abcdEDF)__1256)Hello", &s, 10, MPFR_RNDN); if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "__1256)Hello") ) { printf ("Error for setting NAN (4)\n"); exit (1); } mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */ res = mpfr_strtofr (x, "NAN(abc%dEDF)__1256)Hello", &s, 10, MPFR_RNDN); if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "(abc%dEDF)__1256)Hello") ) { printf ("Error for setting NAN (5)\n"); exit (1); } mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */ res = mpfr_strtofr (x, "NAN((abc))", &s, 10, MPFR_RNDN); if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "((abc))") ) { printf ("Error for setting NAN (6)\n"); exit (1); } mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */ res = mpfr_strtofr (x, "NAN()foo", &s, 10, MPFR_RNDN); if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "foo") ) { printf ("Error for setting NAN (7)\n"); exit (1); } /* Check infinity */ for (i = 0; i <= 0xff; i++) { char t[11] = "+@INFINITY"; /* not char *: this will be modified. */ char *p; int base, j; /* Test all the case variants, assuming ASCII or similar. The first letters are changed first, so that at i = 8, the 2^3 = 8 "INF" case variants have been tested, and they don't need to be tested again for i > 8. */ for (j = 0; j < 8; j++) if ((i >> j) % 2 != 0) t[j+2] += 'a' - 'A'; /* Test "INFINITY", "+INFINITY", "-INFINITY", "INF", "+INF", "-INF", "@INF@", "+@INF@", "-@INF@", up to case changes. */ for (j = 0; j < 9; j++) { if (j == 3) { /* At i = 8, we have tested all the "INF" case variants. */ if (i >= 8) break; t[5] = '\0'; } if (j == 6) { t[1] = '@'; t[5] = '@'; t[6] = '\0'; } if (j % 3 == 1) t[j != 7] = '+'; if (j % 3 == 2) t[j != 8] = '-'; p = t + (j % 3 == 0) + (j < 6); base = randlimb () % (j < 6 ? 17 : 63); if (base == 1) base = 0; res = mpfr_strtofr (x, p, &s, base, MPFR_RNDN); if (res != 0 || !mpfr_inf_p (x) || *s != 0 || (j % 3 != 2 ? MPFR_IS_NEG (x) : MPFR_IS_POS (x))) { printf ("Error for setting \"%s\" in base %d\n s=\"%s\"\n x=", p, base, s); mpfr_dump (x); exit (1); } } } res = mpfr_strtofr (x, "INFANITY", &s, 8, MPFR_RNDN); if (res != 0 || !mpfr_inf_p (x) || strcmp(s, "ANITY")) { printf ("Error for setting INFINITY (2)\n s=%s\n x=", s); mpfr_dump (x); exit (1); } res = mpfr_strtofr (x, "@INF@*2", &s, 11, MPFR_RNDN); if (res != 0 || !mpfr_inf_p (x) || strcmp(s, "*2")) { printf ("Error for setting INFINITY (3)\n s=%s\n x=", s); mpfr_dump (x); exit (1); } /* Check Zero */ res = mpfr_strtofr (x, " 00000", &s, 11, MPFR_RNDN); if (res != 0 || !mpfr_zero_p (x) || s[0] != 0) { printf ("Error for setting ZERO (1)\n s=%s\n x=", s); mpfr_dump (x); exit (1); } /* Check base 62 */ res = mpfr_strtofr (x, "A", NULL, 62, MPFR_RNDN); if (res != 0 || mpfr_cmp_ui (x, 10)) { printf ("Error for setting 'A' in base 62\n x="); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } res = mpfr_strtofr (x, "a", NULL, 62, MPFR_RNDN); if (res != 0 || mpfr_cmp_ui (x, 36)) { printf ("Error for setting 'a' in base 62\n x="); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } res = mpfr_strtofr (x, "Z", NULL, 62, MPFR_RNDN); if (res != 0 || mpfr_cmp_ui (x, 35)) { printf ("Error for setting 'Z' in base 62\n x="); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } res = mpfr_strtofr (x, "z", NULL, 62, MPFR_RNDN); if (res != 0 || mpfr_cmp_ui (x, 61)) { printf ("Error for setting 'z' in base 62\n x="); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } res = mpfr_strtofr (x, "ZA", NULL, 62, MPFR_RNDN); if (res != 0 || mpfr_cmp_ui (x, 2180)) { printf ("Error for setting 'ZA' in base 62\n x="); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } res = mpfr_strtofr (x, "za", NULL, 62, MPFR_RNDN); if (res != 0 || mpfr_cmp_ui (x, 3818)) { printf ("Error for setting 'za' in base 62\n x="); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } res = mpfr_strtofr (x, "aZ", NULL, 62, MPFR_RNDN); if (res != 0 || mpfr_cmp_ui (x, 2267)) { printf ("Error for setting 'aZ' in base 62\n x="); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } res = mpfr_strtofr (x, "Az", NULL, 62, MPFR_RNDN); if (res != 0 || mpfr_cmp_ui (x, 681)) { printf ("Error for setting 'Az' in base 62\n x="); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } /* Check base 60 */ res = mpfr_strtofr (x, "Aa", NULL, 60, MPFR_RNDN); if (res != 0 || mpfr_cmp_ui (x, 636)) { printf ("Error for setting 'Aa' in base 60\n x="); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } res = mpfr_strtofr (x, "Zz", &s, 60, MPFR_RNDN); if (res != 0 || mpfr_cmp_ui (x, 35) || strcmp(s, "z") ) { printf ("Error for setting 'Zz' in base 60\n x="); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } /* Check base 61 */ res = mpfr_strtofr (x, "z", &s, 61, MPFR_RNDN); if (res != 0 || mpfr_cmp_ui (x, 0) || strcmp(s, "z") ) { printf ("Error for setting 'z' in base 61\n x="); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_clear (x); mpfr_clear (y); } /* The following RefTable has been generated by this following code */ #if 0 #define MAX_NUM 100 int randomab (int a, int b) { return a + rand () % (b-a); } int main (void) { int i, base; mpfr_t x; mpfr_prec_t p; mpfr_exp_t e; mpfr_init (x); printf ("struct dymmy_test { \n" " mpfr_prec_t prec; \n" " int base; \n" " const char *str; \n" " const char *binstr; \n" " } RefTable[] = { \n"); for (i = 0 ; i < MAX_NUM ; i++) { p = randomab(2, 180); base = randomab (2, 30); e = randomab (-1<<15, 1<<15); mpfr_set_prec (x, p); mpfr_urandomb (x, RANDS); mpfr_mul_2si (x, x, e, MPFR_RNDN); printf("{%lu, %d,\n\"", p, base); mpfr_out_str (stdout, base, p, x, MPFR_RNDN); printf ("\",\n\""); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); printf ("\"}%c\n", i == MAX_NUM-1 ? ' ' : ',' ); } printf("};\n"); mpfr_clear (x); } #endif static struct dymmy_test { mpfr_prec_t prec; int base; const char *str; const char *binstr; } RefTable[] = { {39, 20, "1.1c9jeh9jg12d8iiggf26b8ce2cig24agai51d9@1445", "1.00111010111010001110110001101011101011e6245"}, {119, 3, "1.2210112120221020220021000020101121120011021202212101222000011110211211122222001001221110102220122021121021101010120101e-5655", "1.1111101110011110001101011100011000011100001011011100010011010010001000000111001010000001110111010100011000110010000000e-8963"}, {166, 18, "3.ecg67g31434b74d8hhbe2dbbb46g9546cae72cae0cfghfh00ed7gebe9ca63b47h08bgbdeb880a76dea12he31e1ccd67e9dh22a911b46h517b745169b2g43egg2e4eah820cdb2132d6a4f9c63505dd4a0dafbc@-5946", "1.011110010000110011111011111100110110010110000010100001101111111000010000011111110101100000010110011001100000010001100101000001101000010010001011001011000110100011001e-24793"}, {139, 4, "1.020302230021023320300300101212330121100031233000032101123133120221012000000000000000000000000000000000000000000000000000000000000000000000e11221", "1.001000110010101100001001001011111000110000110000010001100110111100011001010000001101101111000000001110010001011011011111011000101001000110e22442"}, {126, 13, "4.a3cb351c6c548a0475218519514c6c54366681447019ac70a387862c39c86546ab27608c9c2863328860aa2464288070a76c0773882728c5213a335289259@2897", "1.01011010000001110001100001101111100111011010010111000011000101111011000100001010010100110111101001001001000000011100010000000e10722"}, {6, 26, "1.j79f6@-1593", "1.00000e-7487"}, {26, 18, "3.5e99682hh310aa89hb2fb4h88@-5704", "1.0110010100010101000101100e-23784"}, {12, 21, "4.j7f3e2ccdfa@-3524", "1.10110101011e-15477"}, {38, 28, "o.agr0m367b9bmm76rplg7b53qlj7f02g717cab@6452", "1.1001010011101100110100111000111010001e31021"}, {75, 17, "4.00abd9gc99902e1cae2caa7647gcc029g01370e96d3f8e9g02f814d3ge5faa29d40b9db470@5487", "1.11100000110101010111101001110001001010111111010100000100001010100111011101e22429"}, {91, 16, "1.0a812a627160014a3bda1f00000000000000000000000000000000000000000000000000000000000000000000@7897", "1.000010101000000100101010011000100111000101100000000000010100101000111011110110100001111100e31588"}, {154, 19, "1.989279dda02a8ic15e936ahig3c695f6059a3i01b7d1ge6a418bf84gd87e36061hb2bi62ciagcgb9226fafea41d2ig1e2f0a10ea3i40d6dahf598bdbh372bdf5901gh276866804ah53b6338bi@5285", "1.110101101101101111110010001011110001100000010100011101101001000100110100000011110111000011011101011110010100110101011011111100101101001100000101101000010e22450"}, {53, 2, "1.0100010111100111001010000100011011111011011100110111e-20319", "1.0100010111100111001010000100011011111011011100110111e-20319"}, {76, 3, "2.101212121100222100012112101120011222102000021110201110000202111122221100001e1511", "1.000110101010111000011001011111110000001001101001011011111110111111010000111e2396"}, {31, 9, "1.171774371505084376877631528681e3258", "1.110101101011111011111000110011e10327"}, {175, 8, "4.506242760242070533035566017365410474451421355546570157251400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e3483", "1.001010001100101000101111100000101000100001110001010110110000111011011101100000011110111101011000010001001111001001010011000100010111011011011001101011110000011011110101010011e10451"}, {103, 24, "8.0hmlm3g183cj358fn4bimn5bie1l89k95m647474mm8jg5kh1c011gi0m7de9j7b48c595g1bki4n32kll7b882eg7klgga0h0gf11@4510", "1.001000110101001101011010101001111010110100010100110101010101110000001011001101110110010111000101010111e20681"}, {12, 9, "3.00221080453e2479", "1.11000111010e7859"}, {86, 11, "6.873680186953174a274754118026423965415553a088387303452447389287133a0956111602a5a085446@5035", "1.0000000000110100010110000111010001010100101011000100101010010011101010000110011110001e17421"}, {68, 10, "6.1617378719016284192718392572980535262609909598793237475124371481233e481", "1.0110001011000101110010111101100101111110001100001011110011001101111e1600"}, {11, 15, "5.ab10c18d45@907", "1.0000101111e3546"}, {77, 26, "6.e6kl84g6h30o3nfnj7fjjff4n1ee6e5iop76gabj23e7hgan9o6724domc7bp4hdll95g817519f@5114", "1.1011000101111111111110011011101100000100101000001001100000001011010001001000e24040"}, {28, 27, "d.odiqp9kgh84o8d2aoqg4c21hemi@3566", "1.101001111001111111110011110e16959"}, {45, 14, "7.cddc6295a576980adbc8c16111d6301bad3146a1143c@-6227", "1.10000000110011000000101100110001011100010111e-23706"}, {54, 19, "1.b6e67i2124hfga2g819g1d6527g2b603eg3cd8hhca9gecig8geg1@4248", "1.11010100100010101101110110010100000010111010010101110e18045"}, {49, 20, "1.jj68bj6idadg44figi10d2ji99g6ddi6c6ich96a5h86i529@-3149", "1.001011111101100100001010001000011100000000101110e-13609"}, {171, 16, "6.22cf0e566d8ff11359d70bd9200065cfd72600b12e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000@5602", "1.10001000101100111100001110010101100110110110001111111100010001001101011001110101110000101111011001001000000000000001100101110011111101011100100110000000001011000100101110e22410"}, {144, 14, "1.425d9709b4c125651ab88bb1a0370c14270d067a9a74a612dad48d5c025531c175c1b905201d0d9773aa686c8249db9c0b841b10821791c02baa2525a4aa7571850439c2cc965cd@-3351", "1.11100111110001001101010111010000101010011000111001101011000001011110101110011011100100111001101101111011001001101011001101001011011101101111011e-12759"}, {166, 6, "3.324252232403440543134003140400220120040245215204322153511143504542403430152410543444455151104314552352030352125540101550151410414122051500201022252511512332523431554e8340", "1.010101111101111101001001110010111110010000001111010101100110011011010110011001001100001111010101100000010111011111101110110111101110010001110001111000001010001111000e21560"}, {141, 24, "2.i3c88lkm2958l9ncb9f85kk35namjli84clek5j6jjkli82kb9m4e4i2g39me63db2094cif80gcba8ie6l15ia0d667kn9i1f77bdak599e1ach0j05cdn8kf6c6kfd82j2k6hj2c4d@4281", "1.10011100001010110111001000000000101011100010101011001010001101110100110111011000111101000001111101100000110100100010101011001100100011001011e19629"}, {84, 6, "2.41022133512503223022555143021524424430350133500020112434301542311050052304150111243e982", "1.11010001111111001010011100011000011100100111111010001111010010101001001000011100001e2539"}, {56, 9, "1.5305472255016741401411184703518332515066156086511016413e2936", "1.0111110010001101000000110101110000110101001011001100111e9307"}, {18, 8, "3.63542400000000000e-599", "1.11100111011000101e-1796"}, {111, 13, "8.b693ac7a24679b98708a0057a6202c867bc146740ab1971b380756a24c99804b63436419239ba0510030b819933771a636c57c5747b883@-6160", "1.01011011111110100101110010100100000110000011011101001110010110000011101110111111010111000011011101101001100100e-22792"}, {162, 16, "4.f2abe958a313566adbf3169e55cdcff3785dbd5c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000@382", "1.00111100101010101111101001010110001010001100010011010101100110101011011011111100110001011010011110010101011100110111001111111100110111100001011101101111010101110e1530"}, {117, 23, "2.4b6kk3ag3if217ih1hggkk69bmcecfil1cd38dijh35j8e6ckhd335a4gj7l05bedk19473i8449b1ajc3jd3ka95eceheh72lh2jh17jamlm1142gll@-3628", "1.10010010001010001110011000010000011111011101111100110101100100101111101110010011101001111010100010001111110100101111e-16411"}, {179, 2, "1.1101101011111010101000110101010101101110001011011010101001110111011010011110001000000110101100010010001110010110011000000110001011111001011110100011101000110001001000110100100110e14203", "1.1101101011111010101000110101010101101110001011011010101001110111011010011110001000000110101100010010001110010110011000000110001011111001011110100011101000110001001000110100100110e14203"}, {18, 27, "4.ll743n2f654gh3154@-6039", "1.01101001111010011e-28713"}, {178, 15, "1.e5443105cad2d014b700c42aa3de854c4b95322420695d07db3564ec07473da83bde123b74c794139265a838ebeca745ad3dc97d7c356271ca935ea8e83306562c2a8edc6e886c1b6b2d3e17038379c33826526770985c068@821", "1.011100001000101100111111111111000100110111110011101010001111011001111101111001010011100100100101100011101001000000101001010100011111001011001010011101101001000111111010101101011e3208"}, {161, 22, "2.46ikji624bg042877h8g2jdki4ece6ede62841j7li843a4becdkkii86c54192jkefehikkb3kcb26ij1b3k9agfbb07dih88d6ej0ee0d63i8hedc7f0g0i9g7jf9gf6423j70h421bg5hf2bja9j0a432lb10@-5125", "1.0111011000111110000010011100001100100110001011101001011110111010100000011100000010011101011100101100111100110000001101010101011110100011101111001011001111100000e-22854"}, {62, 19, "7.bgd1g0886a6c3a9ee67cc7g3bgf718i98d90788idi5587358e660iffc0ic6@3257", "1.0101100100001110000100010110100100000111110001111001011110100e13838"}, {127, 19, "1.413bgf99eidba75ged25f7187080bce3h7ebdeghea4ig6c79g94di7b42a3e4cdi4ic6a53i71d2e4hdbe50ih0a0egf2fi469732131ig6g496bf7h8g3c86ie7h@-4465", "1.001101111000011011100010010010010110111001001001110011110101111111000001110101111110001110010000110011111101000011000101111101e-18967"}, {17, 21, "4.7d5b70gh4k0gj4fj@-116", "1.1000100010000110e-508"}, {141, 13, "2.2b4988c5cb57072a6a1a9c42224794a1cbc175a9bc673bb28aa045c3182b9396ca8bb8590969672b0239608a845a2c35c08908a58c2a83748c89241a6561422c7cc4866c8454@4358", "1.10010110101000001000001001111001000100111110100010100110111011111011010010101000110101110000111100010000101101000110000000000001111110110011e16127"}, {39, 7, "3.00350342452505221136410100232265245244e202", "1.10011000111110011010100110101101010010e568"}, {119, 24, "5.2aene587kc2d9a55mm8clhn4dn0a551de58b1fcli8e8hf1jlm7i0376dl5fhb2k8acka03077mnbn9d4dmi0641dce871c81g2b3ge76m3kngm4a9g5gh@-892", "1.0111101010010100001001111110000000100101110010010111111100100101100001010010100110111000101100101010111000101111000010e-4088"}, {41, 14, "5.c3dc5c49373d0c0075624931133022185bd08b16@-5294", "1.0101011000010111111111000010100110011111e-20154"}, {41, 6, "3.2411143454422033245255450304104450302500e2250", "1.1110111101010101001001100000100011110111e5817"}, {17, 13, "3.65789aa26aa273b1@-4490", "1.1100011101010111e-16614"}, {10, 26, "1.5p4hag1fl@6017", "1.110010111e28282"}, {130, 11, "2.606a72601843700427667823172635a47055021a0a68a99326875195a179483948407aa13726244552332114a1784aaa7239956521604460876871a65708458aa@-6285", "1.110001001110111110110111000010101000110010011110010101100100001000101011010010000001000101000110111111110101000100000111100010100e-21742"}, {29, 20, "j.4356d9b7i38i955jjj1j442501bj@163", "1.1010101011110011100000100100e708"}, {140, 21, "9.2f5k7aid6bj2b2g5bff29i73hk3a8d8g0i7ifa07hkb79g4hd3c7j6g4hjj2jbhai01gkje3h9g3gj3i34f0194kaed32iea9dcgcj8h7i1khdkf965c1ak97gf3h03fcab3ggi03fa@4864", "1.0101011100011101000110101001010011111111010011000111111111100000011011100111010001100101100110001110001001100101001100110000011110100101101e21367"}, {133, 13, "2.3721a9107307a71c75c07c83b70a25a9853619030b5bcb55101ca5c2060bca46c331b92b33aa957c3ac7c817335287c6917999c38c3806b6b5919623023ac52063bb@6602", "1.011001101111100001100100110100010100010011100010111110110100100000000010011101001011000100000110011011101001010010011110111100010010e24431"}, {118, 2, "1.001010111011011000100010001110111000001100101000101101010001110110000111101110111011011101111100110010000101001001001e18960", "1.001010111011011000100010001110111000001100101000101101010001110110000111101110111011011101111100110010000101001001001e18960"}, {102, 23, "l.26lhk42clcm9g940eihakhi32gb3331lld488cf1j4f73ge051bfl8gcmcg78gkjc2iibjf752eag0dee6dafa97k79jlh11j3270@-2160", "1.01101011011000100101110111110001011000101101011001011111001101000110111010000010011111101110101100010e-9767"}, {156, 18, "b.eb927dd4g48abee3cc2begehb9c3b8h83cae152db850ac2f3g816d6787825122c8h3aa3g8023h23000a8hg61065b3e367ac59ca373067730f96dd0d3b73b3c43fef91750b333gd497b8ce9228e7@5504", "1.11000110111100011101100011001001110011101100011111010100101110010010010011111001100000011010011111111011001011111010001001011001110001100001101000000110000e22954"}, {158, 5, "3.0112043214104344433122444210142004032004444213123303302023242414000243311324332203224340334422234000104132020124210141322013240010134130441413233111204013422e-10468", "1.1001011000111111110100100101110011100001110100101001101110011001101001101011010010111010111111101010100011100010101100110111011101000110110100000111001100011e-24305"}, {7, 9, "2.141540e-146", "1.001111e-462"}, {111, 5, "3.21233234110011204313222402442032333320324004133424222041314021020411320312421014434003440431230413141402230403e7641", "1.10010000000101010000101010101011011010000100010010010000010110001111000111111111000110111001100101101110101101e17743"}, {76, 13, "7.1c0861453a4ac156b6119ba7548251b5cb00b7c409c2bb8138214676468c9949676226013c1@4639", "1.001000011000000011101101101010100010010001010111100110010101111110110010111e17169"}, {6, 25, "c.aj660@-6978", "1.11000e-32402"}, {156, 3, "2.22101000022222000012110122210202211110020121210120112102122121111210000211020001020201202200011021211102012110220222110022001121011022011202000110120021012e-14744", "1.11010001111000101111110000010011001101000100010010110011100100110001100111011101011111111100011111001100001111100101100000001000001100000000010010001011101e-23368"}, {7, 23, "1.4hclk2@2148", "1.110110e9716"}, {69, 11, "2.77684920493191632416690544493465617a187218365952a6740034288687745a26@3263", "1.01111000111000001111001110000110000110001111110011101100101111011100e11289"}, {146, 21, "3.agg4d0dj636d526d4i8643ch5jee4ge2c3i46k121857dbedagd98cjifaf0fgc09ca739g2fkfbfh06i687kic2kb8c7i48gda57bb6d9bh81eh49h0d8e3i7ad2kgb1ek86b86g3589k27d@3562", "1.0010111111111100101010101010001100110101010011011100001110111000101101001110001110010100000001010001000111010000010011110100010010101100101000001e15647"}, {20, 3, "1.2000000021102111102e-16642", "1.1011101011111110000e-26377"}, {68, 13, "1.a43205b2164676727806614acc0398925569c3962a3ba419881a5c63b651aa3ab46@-618", "1.1111011000001110010100111000110010110110011001110001100101011111000e-2287"}, {129, 4, "2.22033002012102010122130132103000303000120122313322000222121000300000000000000000000000000000000000000000000000000000000000000000e13222", "1.01010001111000010000110010010000100011010011100011110010011000000110011000000011000011010110111111010000000101010011001000000110e26445"}, {22, 6, "1.420033001013011530142e11704", "1.001000110010110110001e30255"}, {108, 6, "1.03345424443433104422104400512453214240453335230205104304115343030341144544051005432030344054100542125304500e7375", "1.00101101110001011101101111000010101011101000001111001110001101100000111100010101010101101100011110111010000e19064"}, {91, 27, "2.ao077kf8oqoihn5pm6f5eqdcgnd2132d7p6n7di8ep82a1a9be99pm36g1emacbenaeiqphpgpdjhmm9ke3pn4pdea@-5482", "1.111101100001000011101010001000000111000100100111110010101101110001101101101101101010111110e-26066"}, {96, 9, "8.25805186310703506315505842015248775712246416686874260383701323213202658278523870037877823670166e-8134", "1.11010111111000011100111001011010001110010001011101011101110101000101100100100010110011001010000e-25782"}, {161, 16, "7.3a7627c1e42ef738698e292f0b81728c4b14fe8c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000@-3342", "1.1100111010011101100010011111000001111001000010111011110111001110000110100110001110001010010010111100001011100000010111001010001100010010110001010011111110100011e-13366"}, {90, 3, "2.10212200011211012002002221112120210222002020100202111000211012122020011102022112222021001e-3447", "1.11100010111011011000101111110001000101000111110001100001010111101101011011110001000010001e-5463"}, {100, 27, "a.f81hjjakdnc021op6ffh530ec8ige6n2fqc8f8j7ia7qelebgqkm4ic5ohh652hq1kgpag6pp0ldin6ce1fg6mj34077f5qc5oe@6576", "1.011101001010010011110001100011111111010001110110100100101001010000101011101011110010010011111100000e31271"}, {152, 16, "e.37ac48a0303f903c9d20883eddea4300d1190000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000@-1388", "1.1100011011110101100010010001010000000110000001111111001000000111100100111010010000010001000001111101101110111101010010000110000000011010001000110010000e-5549"}, {106, 20, "1.3g2h7i2776d50gjibi937f8cdci3idecdeh3j2gba0j8d1ghgg3eg609ji55h5g7jeai1bii3a4f9jhjfij6jd1g3cg0f6024e252gc3e@6422", "1.100110000101011010100111100110000000100101000110110011010010000101000100110010001110011110111100010000111e27755"}, {23, 17, "9.f72e724454d1g0f60g93g6@-6563", "1.0011100011110110010001e-26823"}, {98, 6, "1.2444223304453415235424343034030405514010421403514410005234221430055051205523402412055242134042045e-8535", "1.1101110011010001101001001111100101111010100111001011110001000010100101101110011011101100000111011e-22063"}, {4, 18, "1.gec@-6711", "1.100e-27984"}, {69, 24, "8.d45gdfnhkhb7a20nj96dnggic83imhjne0cceldechn1m4e9fbd9db0ablngjf9n7810@6975", "1.00100111111100101100110011110110110000110110110010100101011111000100e31983"}, {122, 8, "4.0227760456667717717077553523466457265600000000000000000000000000000000000000000000000000000000000000000000000000000000000e-1767", "1.0000001001011111111000010010111011011011111100111111100111100011111110110101110101001110011011010010111101011010111000000e-5299"}, {144, 23, "8.b01c48dg20bek9a5k376clc501aecg92bdjaeji2dm9230i7j3k36jm50b0c5a0753i2b18534cji34bcl2li033cc534m52k2gbegc25a5g30lf4calag58026i5d7li61jg9digj5ceb1@-4456", "1.00010000110011010111011011110111001101111001010110001101011100100101101110110000010011011111100000100110001001001111111011010110000000001111110e-20154"}, {111, 4, "2.23100111310122202021232133233012212012232222323230133100000000000000000000000000000000000000000000000000000000e-10458", "1.01011010000010101110100011010100010001001101110011111101111000110100110000110101110101010111011101100011111010e-20915"}, {117, 10, "1.61207328685870427963864999744776917701013812304254540861834226053316419217753608451422967376154318603744156166920074e-6440", "1.01100011000100111001100010000000110010100001001011111010100001101111100100101100111010100011101110001010011010010010e-21393"}, {106, 16, "1.dd30a1d24091263243ca1c144f0000000000000000000000000000000000000000000000000000000000000000000000000000000@354", "1.110111010011000010100001110100100100000010010001001001100011001001000011110010100001110000010100010011110e1416"}, {77, 14, "4.90d6913ba57b149d8d85a58c311b4d537c10bd7d3c10d69c62bc08d32269760126a58115a105@-7311", "1.1001000000111100000111001001011000110101001111100001100111010100010000011111e-27834"}, {8, 4, "3.2230000e15197", "1.1101011e30395"}, {81, 24, "1.84ni25h558abmhg2dk7bl2jbbmkf4i8i2bemc5cgmk9jf301c00k24271m9h7mgm4301be1lnldn4364@2573", "1.01110010011000110110100101011001011111101111101100010110101101011101100001000010e11797"}, {94, 2, "1.010010010101111001001011111111100100011110110100010001101111111100100101101100110101001011111e32427", "1.010010010101111001001011111111100100011110110100010001101111111100100101101100110101001011111e32427"}, {77, 21, "1.87e4k9df85g50ead6fcj4h86820ikdjdjg93d90ca406g470hhkh7ciaba1aggg753g36553ebh5@2538", "1.0010001100011000111010000010011001010011000000100101010001100000111101000111e11148"}, {80, 17, "1.923gga999230g94fce02efg753ce001045a35e0264c9c2cb17850e32484fc3526dcg38ed874g5f2@3392", "1.0011100111101001001101111001110100001100111110011110110001100110101010111001110e13865"}, {99, 7, "4.53646362336126606650465342500160461331562113222506144210636341332436342025203333264316511653025011e-5540", "1.01101101111001001100001101101101010011001001100110111000010000101000011001001001101000011101011001e-15551"}, {119, 20, "1.c8966iabcf4de94ad15f9e83j407i3he7fch54h5jh0g5d74e06c057gg72a107didj8d1j8geibbfec5j36c3fgd5e12edjb9g10j7c9i03f33hi80ce0@7153", "1.0101110101100011110001001110100110011000100000001001000110111110011111100011111010011101011111101101010011110111110100e30915"}, {93, 13, "2.c749cb562c3a758b1a21a650666a4c6c53c76ca58a1a75a0358c9ac3866887972b3551a03aa6c150856531258508@193", "1.10101111101001011010111101100100111110011111010110111101100100010011001001100011110100111110e715"}, {145, 14, "1.c61614b64261d22c62cb9d16163ca4d144ac23351b708506b3b610b1b67b764ca974448d7a2c6515a6bc97503d4b2a530c75b2b677a464c6629c69b6c3d7860d7749b4b653c434d5@2050", "1.111111100001101111100011001111100010010000101000011110000001110100111001011010100001001010111111010001111101000110011000011101110110001001100101e7805"}, {159, 23, "4.bj9l07l0215e7l6lf1dkf62i056l37jaa0gdih717656f1kk1a77883jf99jg31le43em76bmcg4lddl782ihkla0m392886d8lm67d6c3a1l4j12kg0l1k52ee77lmk0gech11g8jeei680k85bi460c7el17@-1539", "1.01010100110100100101100001011100000001100011110001001101000010000001000010000110000110010001110100001101011101101001001101101111001101101111101001010010010100e-6960"}, {24, 25, "g.m749al09kflg5b42jnn4a7b@-2820", "1.01010010101011010111011e-13092"}, {88, 18, "3.5ed0gad0bhhb7aa9ge2ad1dhcg6833f3e068936hghf23gd2aa69f13539f15hfce50aa64achfee49bfg7249g@-4058", "1.001000010110011011000101100000101111101001100011101101001111110111000010010110010001100e-16920"} }; static void check_reftable (void) { int i, base; mpfr_t x, y; mpfr_prec_t p; char *s; mpfr_init2 (x, 200); mpfr_init2 (y, 200); for (i = 0 ; i < numberof (RefTable) ; i++) { base = RefTable[i].base; p = RefTable[i].prec; mpfr_set_prec (x, p); mpfr_set_prec (y, p); mpfr_set_str_binary (x, RefTable[i].binstr); mpfr_strtofr (y, RefTable[i].str, &s, base, MPFR_RNDN); if (s == NULL || *s != 0) { printf ("strtofr didn't parse entire input for i=%d:\n" " Str=%s", i, RefTable[i].str); exit (1); } if (mpfr_cmp (x, y)) { printf ("Results differ between strtofr and set_binary for i=%d:\n" " Set binary gives: ", i); mpfr_dump (x); printf (" strtofr gives: "); mpfr_dump (y); printf (" setstr gives: "); mpfr_set_str (x, RefTable[i].str, base, MPFR_RNDN); mpfr_dump (x); mpfr_set_prec (x, 2*p); mpfr_set_str (x, RefTable[i].str, base, MPFR_RNDN); printf (" setstr ++ gives: "); mpfr_dump (x); exit (1); } } mpfr_clear (y); mpfr_clear (x); } static void check_parse (void) { mpfr_t x; char *s; int res; mpfr_init (x); /* Invalid data */ mpfr_set_si (x, -1, MPFR_RNDN); res = mpfr_strtofr (x, " invalid", NULL, 10, MPFR_RNDN); if (MPFR_NOTZERO (x) || MPFR_IS_NEG (x)) { printf ("Failed parsing ' invalid' (1)\n X="); mpfr_dump (x); exit (1); } MPFR_ASSERTN (res == 0); mpfr_set_si (x, -1, MPFR_RNDN); res = mpfr_strtofr (x, " invalid", &s, 0, MPFR_RNDN); if (MPFR_NOTZERO (x) || MPFR_IS_NEG (x) || strcmp (s, " invalid")) { printf ("Failed parsing ' invalid' (2)\n S=%s\n X=", s); mpfr_dump (x); exit (1); } MPFR_ASSERTN (res == 0); /* Check if it stops correctly */ mpfr_strtofr (x, "15*x", &s, 10, MPFR_RNDN); if (mpfr_cmp_ui (x, 15) || strcmp (s, "*x")) { printf ("Failed parsing '15*x'\n S=%s\n X=", s); mpfr_dump (x); exit (1); } /* Check for leading spaces */ mpfr_strtofr (x, " 1.5E-10 *x^2", &s, 10, MPFR_RNDN); if (mpfr_cmp_str1 (x, "1.5E-10") || strcmp (s, " *x^2")) { printf ("Failed parsing '1.5E-10*x^2'\n S=%s\n X=", s); mpfr_dump (x); exit (1); } /* Check for leading sign */ mpfr_strtofr (x, " +17.5E-42E ", &s, 10, MPFR_RNDN); if (mpfr_cmp_str1 (x, "17.5E-42") || strcmp (s, "E ")) { printf ("Failed parsing '+17.5E-42E '\n S=%s\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "-17.5E+42E\n", &s, 10, MPFR_RNDN); if (mpfr_cmp_str1 (x, "-17.5E42") || strcmp (s, "E\n")) { printf ("Failed parsing '-17.5E+42\\n'\n S=%s\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } /* P form */ mpfr_strtofr (x, "0x42P17", &s, 16, MPFR_RNDN); if (mpfr_cmp_str (x, "8650752", 10, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '0x42P17' (base = 16)\n S='%s'\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "-0X42p17", &s, 16, MPFR_RNDN); if (mpfr_cmp_str (x, "-8650752", 10, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '-0x42p17' (base = 16)\n S='%s'\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "42p17", &s, 16, MPFR_RNDN); if (mpfr_cmp_str (x, "8650752", 10, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '42p17' (base = 16)\n S='%s'\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "-42P17", &s, 16, MPFR_RNDN); if (mpfr_cmp_str (x, "-8650752", 10, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '-42P17' (base = 16)\n S='%s'\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "0b1001P17", &s, 2, MPFR_RNDN); if (mpfr_cmp_str (x, "1179648", 10, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '0b1001P17' (base = 2)\n S='%s'\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "-0B1001p17", &s, 2, MPFR_RNDN); if (mpfr_cmp_str (x, "-1179648", 10, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '-0B1001p17' (base = 2)\n S='%s'\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "1001p17", &s, 2, MPFR_RNDN); if (mpfr_cmp_str (x, "1179648", 10, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '1001p17' (base = 2)\n S='%s'\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "-1001P17", &s, 2, MPFR_RNDN); if (mpfr_cmp_str (x, "-1179648", 10, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '-1001P17' (base = 2)\n S='%s'\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } /* Check for auto-detection of the base */ mpfr_strtofr (x, "+0x42P17", &s, 0, MPFR_RNDN); if (mpfr_cmp_str (x, "42P17", 16, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '+0x42P17'\n S=%s\n X=", s); mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "-42E17", &s, 0, MPFR_RNDN); if (mpfr_cmp_str (x, "-42E17", 10, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '-42E17'\n S=%s\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "-42P17", &s, 0, MPFR_RNDN); if (mpfr_cmp_str (x, "-42", 10, MPFR_RNDN) || strcmp (s, "P17")) { printf ("Failed parsing '-42P17' (base = 0)\n S='%s'\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, " 0b0101.011@42", &s, 0, MPFR_RNDN); if (mpfr_cmp_str (x, "0101.011@42", 2, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '0101.011@42'\n S=%s\n X=", s); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, " 0b0101.011P42", &s, 0, MPFR_RNDN); if (mpfr_cmp_str (x, "0101.011@42", 2, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '0101.011@42'\n S=%s\n X=", s); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "+0x42@17", &s, 0, MPFR_RNDN); if (mpfr_cmp_str (x, "4.2@18", 16, MPFR_RNDN) || *s != 0) { printf ("Failed parsing '+0x42P17'\n S=%s\n X=", s); mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } /* Check for space inside the mantissa */ mpfr_strtofr (x, "+0x4 2@17", &s, 0, MPFR_RNDN); if (mpfr_cmp_ui (x, 4) || strcmp(s," 2@17")) { printf ("Failed parsing '+0x4 2@17'\n S=%s\n X=", s); mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "+0x42 P17", &s, 0, MPFR_RNDN); if (mpfr_cmp_ui (x, 0x42) || strcmp(s," P17")) { printf ("Failed parsing '+0x42 P17'\n S=%s\n X=", s); mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } /* Space between mantissa and exponent */ mpfr_strtofr (x, " -0b0101P 17", &s, 0, MPFR_RNDN); if (mpfr_cmp_si (x, -5) || strcmp(s,"P 17")) { printf ("Failed parsing '-0b0101P 17'\n S=%s\n X=", s); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } /* Check for Invalid exponent. */ mpfr_strtofr (x, " -0b0101PF17", &s, 0, MPFR_RNDN); if (mpfr_cmp_si (x, -5) || strcmp(s,"PF17")) { printf ("Failed parsing '-0b0101PF17'\n S=%s\n X=", s); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } /* At least one digit in the mantissa. */ mpfr_strtofr (x, " .E10", &s, 0, MPFR_RNDN); if (strcmp(s," .E10")) { printf ("Failed parsing ' .E10'\n S=%s\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } /* Check 2 '.': 2.3.4 */ mpfr_strtofr (x, "-1.2.3E4", &s, 0, MPFR_RNDN); if (mpfr_cmp_str1 (x, "-1.2") || strcmp(s,".3E4")) { printf ("Failed parsing '-1.2.3E4'\n S=%s\n X=", s); mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } /* Check for 0x and 0b */ mpfr_strtofr (x, " 0xG", &s, 0, MPFR_RNDN); if (mpfr_cmp_ui (x, 0) || strcmp(s,"xG")) { printf ("Failed parsing ' 0xG'\n S=%s\n X=", s); mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, " 0b2", &s, 0, MPFR_RNDN); if (mpfr_cmp_ui (x, 0) || strcmp(s,"b2")) { printf ("Failed parsing ' 0b2'\n S=%s\n X=", s); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, "-0x.23@2Z33", &s, 0, MPFR_RNDN); if (mpfr_cmp_si (x, -0x23) || strcmp(s,"Z33")) { printf ("Failed parsing '-0x.23@2Z33'\n S=%s\n X=", s); mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_strtofr (x, " 0x", &s, 0, MPFR_RNDN); if (mpfr_cmp_ui (x, 0) || strcmp(s,"x")) { printf ("Failed parsing ' 0x'\n S=%s\n X=", s); mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); exit (1); } mpfr_clear (x); } static void check_overflow (void) { mpfr_t x; char *s; mpfr_init (x); /* Huge overflow */ mpfr_strtofr (x, "123456789E2147483646", &s, 0, MPFR_RNDN); if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x) ) { printf ("Check overflow failed (1) with:\n s=%s\n x=", s); mpfr_dump (x); exit (1); } mpfr_strtofr (x, "123456789E9223372036854775807", &s, 0, MPFR_RNDN); if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x) ) { printf ("Check overflow failed (2) with:\n s='%s'\n x=", s); mpfr_dump (x); #if defined(__GNUC__) printf ("This failure is triggered by GCC bug 86554:\n" " https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86554\n" " https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87276 " "(about this test)\nWorkaround: disable code hoisting " "with -fno-code-hoisting in CFLAGS.\n"); /* Note: In Debian, this error is obtained with gcc-snapshot from 20180908-1 to 20181127-1. With gcc-snapshot from 20181209-1 to 20190102-1 (at least), the MPFR build no longer seems affected in general, but using --with-gmp-build=... together with --enable-assert still triggers this failure. This bug has been fixed in the GCC trunk rev 267725, thus the future gcc-snapshot versions should no longer have this bug. */ #endif exit (1); } mpfr_strtofr (x, "123456789E170141183460469231731687303715884105728", &s, 0, MPFR_RNDN); if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x) ) { printf ("Check overflow failed (3) with:\n s=%s\n x=", s); mpfr_dump (x); exit (1); } /* Limit overflow */ mpfr_strtofr (x, "12E2147483646", &s, 0, MPFR_RNDN); if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x) ) { printf ("Check overflow failed (4) with:\n s=%s\n x=", s); mpfr_dump (x); exit (1); } mpfr_strtofr (x, "12E2147483645", &s, 0, MPFR_RNDN); if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x)) { printf ("Check overflow failed (5) with:\n s=%s\n x=", s); mpfr_dump (x); exit (1); } mpfr_strtofr (x, "0123456789ABCDEF@2147483640", &s, 16, MPFR_RNDN); if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x)) { printf ("Check overflow failed (6) with:\n s=%s\n x=", s); mpfr_dump (x); exit (1); } mpfr_strtofr (x, "0123456789ABCDEF@540000000", &s, 16, MPFR_RNDN); if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x)) { printf ("Check overflow failed (7) with:\n s=%s\n x=", s); mpfr_dump (x); exit (1); } mpfr_strtofr (x, "1@2305843009213693951", &s, 16, MPFR_RNDN); if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x)) { printf ("Check overflow failed (8) with:\n s=%s\n x=", s); mpfr_dump (x); exit (1); } mpfr_strtofr (x, "1@2305843009213693951", &s, 17, MPFR_RNDN); if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x)) { printf ("Check overflow failed (9) with:\n s=%s\n x=", s); mpfr_dump (x); exit (1); } /* Check underflow */ mpfr_strtofr (x, "123456789E-2147483646", &s, 0, MPFR_RNDN); if (s[0] != 0 || !MPFR_IS_ZERO (x) || !MPFR_IS_POS (x) ) { printf ("Check underflow failed (1) with:\n s=%s\n x=", s); mpfr_dump (x); exit (1); } mpfr_strtofr (x, "123456789E-9223372036854775807", &s, 0, MPFR_RNDN); if (s[0] != 0 || !MPFR_IS_ZERO (x) || !MPFR_IS_POS (x) ) { printf ("Check underflow failed (2) with:\n s='%s'\n x=", s); mpfr_dump (x); exit (1); } mpfr_strtofr (x, "-123456789E-170141183460469231731687303715884105728", &s, 0, MPFR_RNDN); if (s[0] != 0 || !MPFR_IS_ZERO (x) || !MPFR_IS_NEG (x) ) { printf ("Check underflow failed (3) with:\n s=%s\n x=", s); mpfr_dump (x); exit (1); } mpfr_strtofr (x, "0123456789ABCDEF@-540000000", &s, 16, MPFR_RNDN); if (s[0] != 0 || !MPFR_IS_ZERO (x) || !MPFR_IS_POS (x)) { printf ("Check overflow failed (7) with:\n s=%s\n x=", s); mpfr_dump (x); exit (1); } mpfr_strtofr (x, "1@-2305843009213693952", &s, 16, MPFR_RNDN); if (s[0] != 0 || !MPFR_IS_ZERO (x) || !MPFR_IS_POS (x) ) { printf ("Check underflow failed (8) with:\n s='%s'\n x=", s); mpfr_dump (x); exit (1); } mpfr_clear (x); } static void check_retval (void) { mpfr_t x; int res; mpfr_init2 (x, 10); res = mpfr_strtofr (x, "01011000111", NULL, 2, MPFR_RNDN); MPFR_ASSERTN (res == 0); res = mpfr_strtofr (x, "11011000111", NULL, 2, MPFR_RNDN); MPFR_ASSERTN (res > 0); res = mpfr_strtofr (x, "110110001101", NULL, 2, MPFR_RNDN); MPFR_ASSERTN (res < 0); mpfr_clear (x); } /* Bug found by Christoph Lauter (in mpfr_set_str). */ static struct bug20081025_test { mpfr_rnd_t rnd; int inexact; const char *str; const char *binstr; } Bug20081028Table[] = { {MPFR_RNDN, -1, "1.00000000000000000006", "1"}, {MPFR_RNDZ, -1, "1.00000000000000000006", "1"}, {MPFR_RNDU, +1, "1.00000000000000000006", "10000000000000000000000000000001e-31"}, {MPFR_RNDD, -1, "1.00000000000000000006", "1"}, {MPFR_RNDN, +1, "-1.00000000000000000006", "-1"}, {MPFR_RNDZ, +1, "-1.00000000000000000006", "-1"}, {MPFR_RNDU, +1, "-1.00000000000000000006", "-1"}, {MPFR_RNDD, -1, "-1.00000000000000000006", "-10000000000000000000000000000001e-31"}, {MPFR_RNDN, +1, "0.999999999999999999999999999999999999999999999", "1"}, {MPFR_RNDZ, -1, "0.999999999999999999999999999999999999999999999", "11111111111111111111111111111111e-32"}, {MPFR_RNDU, +1, "0.999999999999999999999999999999999999999999999", "1"}, {MPFR_RNDD, -1, "0.999999999999999999999999999999999999999999999", "11111111111111111111111111111111e-32"}, {MPFR_RNDN, -1, "-0.999999999999999999999999999999999999999999999", "-1"}, {MPFR_RNDZ, +1, "-0.999999999999999999999999999999999999999999999", "-11111111111111111111111111111111e-32"}, {MPFR_RNDU, +1, "-0.999999999999999999999999999999999999999999999", "-11111111111111111111111111111111e-32"}, {MPFR_RNDD, -1, "-0.999999999999999999999999999999999999999999999", "-1"} }; static void bug20081028 (void) { int i; int inexact, res; mpfr_rnd_t rnd; mpfr_t x, y; char *s; mpfr_init2 (x, 32); mpfr_init2 (y, 32); for (i = 0 ; i < numberof (Bug20081028Table) ; i++) { rnd = Bug20081028Table[i].rnd; inexact = Bug20081028Table[i].inexact; mpfr_set_str_binary (x, Bug20081028Table[i].binstr); res = mpfr_strtofr (y, Bug20081028Table[i].str, &s, 10, rnd); if (s == NULL || *s != 0) { printf ("Error in Bug20081028: strtofr didn't parse entire input\n" "for (i=%d) Str=\"%s\"", i, Bug20081028Table[i].str); exit (1); } if (! SAME_SIGN (res, inexact)) { printf ("Error in Bug20081028: expected %s ternary value, " "got %d\nfor (i=%d) Rnd=%s Str=\"%s\"\n Set binary gives: ", inexact > 0 ? "positive" : "negative", res, i, mpfr_print_rnd_mode(rnd), Bug20081028Table[i].str); mpfr_dump (x); printf (" strtofr gives: "); mpfr_dump (y); exit (1); } if (mpfr_cmp (x, y)) { printf ("Error in Bug20081028: Results differ between strtofr and " "set_binary\nfor (i=%d) Rnd=%s Str=\"%s\"\n" " Set binary gives: ", i, mpfr_print_rnd_mode(rnd), Bug20081028Table[i].str); mpfr_dump (x); printf (" strtofr gives: "); mpfr_dump (y); exit (1); } } mpfr_clear (y); mpfr_clear (x); } /* check that 1.23e is correctly parsed, cf https://gmplib.org/list-archives/gmp-bugs/2010-March/001898.html */ static void test20100310 (void) { mpfr_t x, y; char str[] = "1.23e", *endptr; mpfr_init2 (x, 53); mpfr_init2 (y, 53); mpfr_strtofr (x, str, &endptr, 10, MPFR_RNDN); mpfr_strtofr (y, "1.23", NULL, 10, MPFR_RNDN); if (mpfr_cmp (x, y) != 0) { printf ("x <> y in test20100310\n"); exit (1); } if (endptr != str + 4) /* strtofr should take into account '1.23', not '1.23e' */ { printf ("endptr <> str + 4 in test20100310\n"); exit (1); } mpfr_clear (x); mpfr_clear (y); } /* From a bug reported by Joseph S. Myers https://sympa.inria.fr/sympa/arc/mpfr/2012-08/msg00005.html */ static void bug20120814 (void) { mpfr_exp_t emin = -30, e; mpfr_t x, y; int r; char s[64], *p; mpfr_init2 (x, 2); mpfr_set_ui_2exp (x, 3, emin - 2, MPFR_RNDN); mpfr_get_str (s + 1, &e, 10, 19, x, MPFR_RNDD); s[0] = s[1]; s[1] = '.'; for (p = s; *p != 0; p++) ; *p = 'e'; sprintf (p + 1, "%d", (int) e - 1); mpfr_init2 (y, 4); r = mpfr_strtofr (y, s, NULL, 0, MPFR_RNDN); if (r <= 0 || ! mpfr_equal_p (x, y)) { printf ("Error in bug20120814\n"); printf ("mpfr_strtofr failed on string \"%s\"\n", s); printf ("Expected inex > 0 and y = 0.1100E%d\n", (int) emin); printf ("Got inex = %-6d and y = ", r); mpfr_dump (y); exit (1); } mpfr_clear (x); mpfr_clear (y); } static void bug20120829 (void) { mpfr_t x1, x2, e; int inex1, inex2, i, r; char s[48] = "1e-1"; mpfr_init2 (e, 128); mpfr_inits2 (4, x1, x2, (mpfr_ptr) 0); inex1 = mpfr_set_si (e, -1, MPFR_RNDN); MPFR_ASSERTN (inex1 == 0); for (i = 1; i <= sizeof(s) - 5; i++) { s[3+i] = '0'; s[4+i] = 0; inex1 = mpfr_mul_ui (e, e, 10, MPFR_RNDN); MPFR_ASSERTN (inex1 == 0); RND_LOOP_NO_RNDF (r) { mpfr_rnd_t rnd = (mpfr_rnd_t) r; inex1 = mpfr_exp10 (x1, e, rnd); inex1 = VSIGN (inex1); inex2 = mpfr_strtofr (x2, s, NULL, 0, rnd); inex2 = VSIGN (inex2); /* On 32-bit machines, for i = 7, r8389, r8391 and r8394 do: strtofr.c:...: MPFR assertion failed: cy == 0 r8396 is OK. On 64-bit machines, for i = 15, r8389 does: strtofr.c:678: MPFR assertion failed: err < (64 - 0) r8391 does: strtofr.c:680: MPFR assertion failed: h < ysize r8394 and r8396 are OK. */ if (! mpfr_equal_p (x1, x2) || inex1 != inex2) { printf ("Error in bug20120829 for i = %d, rnd = %s\n", i, mpfr_print_rnd_mode (rnd)); printf ("Expected inex = %d, x = ", inex1); mpfr_dump (x1); printf ("Got inex = %d, x = ", inex2); mpfr_dump (x2); exit (1); } } } mpfr_clears (e, x1, x2, (mpfr_ptr) 0); } /* https://sympa.inria.fr/sympa/arc/mpfr/2016-12/msg00043.html mpfr_strtofr can return an incorrect ternary value. Note: As a consequence, the value can also be incorrect if the current exponent range is not the maximum one (since the ternary value is used to resolve double rounding in mpfr_check_range); this can happen only if the value is a midpoint between 0 and the minimum positive number or the opposite. */ static void bug20161217 (void) { mpfr_t fp, z; static const char * num = "0.1387778780781445675529539585113525390625e31"; /* The above number is 5^47/2^9. */ int inex; mpfr_init2 (fp, 110); mpfr_init2 (z, 110); inex = mpfr_strtofr (fp, num, NULL, 10, MPFR_RNDN); MPFR_ASSERTN(inex == 0); mpfr_set_str_binary (z, "10001100001000010011110110011101101001010000001011011110010001010100010100100110111101000010001011001100001101E-9"); MPFR_ASSERTN(mpfr_equal_p (fp, z)); /* try with 109 bits */ mpfr_set_prec (fp, 109); inex = mpfr_strtofr (fp, num, NULL, 10, MPFR_RNDN); MPFR_ASSERTN(inex < 0); mpfr_set_str_binary (z, "10001100001000010011110110011101101001010000001011011110010001010100010100100110111101000010001011001100001100E-9"); MPFR_ASSERTN(mpfr_equal_p (fp, z)); mpfr_clear (fp); mpfr_clear (z); } /* check bug in MPFR 3.1.5 is fixed: cf https://sympa.inria.fr/sympa/arc/mpfr/2017-03/msg00009.html Note: same bug as bug20161217. See also the comments of bug20161217; here, this is a case where the value is incorrect. */ static void bug20170308 (void) { mpfr_exp_t emin; /* the following is slightly larger than 2^-1075, thus should be rounded to 0.5*2^-1074, with ternary value < 0 */ char str[] = "2.47032822920623272089E-324"; mpfr_t z; int inex; emin = mpfr_get_emin (); mpfr_init2 (z, 53); set_emin (-1073); /* with emin = -1073, the smallest positive number is 0.5*2^emin = 2^(-1074), thus str should be rounded to 2^(-1074) with inex > 0 */ inex = mpfr_strtofr (z, str, NULL, 10, MPFR_RNDN); MPFR_ASSERTN(inex > 0 && mpfr_cmp_ui_2exp (z, 1, -1074) == 0); set_emin (-1074); /* with emin = -1074, str should be rounded to 2^(-1075) with inex < 0 */ inex = mpfr_strtofr (z, str, NULL, 10, MPFR_RNDN); MPFR_ASSERTN(inex < 0 && mpfr_cmp_ui_2exp (z, 1, -1075) == 0); mpfr_clear (z); set_emin (emin); } /* r13299 fails with 8-bit limbs (micro-gmp/8). */ static void bug20181127 (void) { char s[] = "9.Z6nrLVSMG1bDcCF2ONJdX@-183295525"; /* base 58 */ mpfr_t x, y; mpfr_inits2 (6, x, y, (mpfr_ptr) 0); mpfr_set_ui_2exp (x, 5, -1073741701, MPFR_RNDN); mpfr_strtofr (y, s, NULL, 58, MPFR_RNDZ); if (! mpfr_equal_p (x, y)) { printf ("Error in bug20181127 on %s (base 58)\n", s); printf ("Expected x = "); mpfr_dump (x); printf ("Got y = "); mpfr_dump (y); printf ("*Note* In base 58, x ~= "); mpfr_out_str (stdout, 58, 8, x, MPFR_RNDN); printf ("\n"); exit (1); } mpfr_clears (x, y, (mpfr_ptr) 0); } static void coverage (void) { #if _MPFR_EXP_FORMAT >= 3 && _MPFR_PREC_FORMAT == 3 && MPFR_PREC_BITS == 64 char str3[] = "1@-2112009130072406892"; char str31[] = "1@-511170973314085831"; mpfr_t x; int inex; mpfr_exp_t emin; /* exercise assertion cy == 0 around line 698 of strtofr.c */ emin = mpfr_get_emin (); set_emin (mpfr_get_emin_min ()); /* emin = -4611686018427387903 on a 64-bit machine */ mpfr_init2 (x, 1); inex = mpfr_strtofr (x, str3, NULL, 3, MPFR_RNDN); /* 3^-2112009130072406892 is slightly larger than (2^64)^-52303988630398057 thus we should get inex < 0 */ MPFR_ASSERTN(inex < 0); MPFR_ASSERTN(mpfr_cmp_ui_2exp (x, 1, -52303988630398057 * 64) == 0); inex = mpfr_strtofr (x, str31, NULL, 31, MPFR_RNDN); /* 31^-511170973314085831 is slightly smaller than (2^64)^-39569396093273623 thus we should get inex > 0 */ MPFR_ASSERTN(inex > 0); MPFR_ASSERTN(mpfr_cmp_ui_2exp (x, 1, -39569396093273623 * 64) == 0); mpfr_clear (x); set_emin (emin); #endif } #define BSIZE 512 static void random_tests (void) { char s0[BSIZE], s1[BSIZE], s2[BSIZE+64]; mpfr_t x0, x1, x2; int prec, i; for (prec = MPFR_PREC_MIN; prec < 300; prec++) { mpfr_inits2 (prec, x0, x1, x2, (mpfr_ptr) 0); for (i = 0; i < 20; i++) { const char *num_to_text; mpfr_exp_t e0, e1; int base, j, k, neg; int noteq = 0; char d; /* We want the same exponent for x0 and its successor x1. This is not possible for precision 1 in base 2. */ do base = 2 + (randlimb () % 61); while (prec == 1 && base == 2); num_to_text = base <= 36 ? num_to_text36 : num_to_text62; do { /* Let's consider only positive numbers. We should test negative numbers, but they should be built later, just for the test itself. */ tests_default_random (x0, 0, mpfr_get_emin (), mpfr_get_emax (), 1); mpfr_set (x1, x0, MPFR_RNDN); mpfr_nextabove (x1); mpfr_get_str (s0, &e0, base, BSIZE - 1, x0, MPFR_RNDU); mpfr_get_str (s1, &e1, base, BSIZE - 1, x1, MPFR_RNDD); } while (! (mpfr_regular_p (x0) && mpfr_regular_p (x1) && e0 == e1)); /* 0 < x0 <= (s0,e) <= (s1,e) <= x1 with e = e0 = e1. Let's build a string s2 randomly formed by: - the common prefix of s0 and s1; - some of the following digits of s0 (possibly none); - the next digit of s0 + 1; - some of the following digits of s1 (possibly none). Then 0 < x0 <= (s0,e) < (s2,e) <= (s1,e) <= x1, and with a very high probability that (s2,e) < (s1,e); noteq is set to true in this case. For instance, if: s0 = 123456789 s1 = 124012345 one can have, e.g.: s2 = 12345734 s2 = 123556789 s2 = 124 s2 = 124012 s2 is not taken completely randomly between s0 and s1, but it will be built rather easily, and with the randomness of x0, we should cover all cases, with s2 very close to s0, s2 very close to s1, or not too close to either. */ neg = randlimb () & 1; s2[0] = neg ? '-' : '+'; s2[1] = '.'; for (j = 0; MPFR_ASSERTN (s0[j] != 0 && s1[j] != 0), s0[j] == s1[j]; j++) s2[j+2] = s0[j]; /* k is the position of the first differing digit. */ k = j; while (j < BSIZE - 2 && randlimb () % 8 != 0) { MPFR_ASSERTN (s0[j] != 0); s2[j+2] = s0[j]; j++; } MPFR_ASSERTN (s0[j] != 0); /* We will increment the next digit. Thus while s0[j] is the maximum digit, go back until this is no longer the case (the first digit after the common prefix cannot be the maximum digit, so that we will stop early enough). */ while ((d = s0[j]) == num_to_text[base - 1]) j--; noteq = j != k; s2[j+2] = d = *(strchr (num_to_text, d) + 1); if (d != s1[j]) noteq = 1; j++; while (j < BSIZE - 1 && randlimb () % 8 != 0) { MPFR_ASSERTN (s1[j] != 0); s2[j+2] = s1[j]; j++; } sprintf (s2 + (j+2), "@%" MPFR_EXP_FSPEC "d", (mpfr_eexp_t) e0); while (noteq == 0 && j < BSIZE - 1) { if (s1[j] != '0') noteq = 1; j++; } if (neg) { mpfr_neg (x0, x0, MPFR_RNDN); mpfr_neg (x1, x1, MPFR_RNDN); } if (noteq) { mpfr_strtofr (x2, s2, NULL, base, MPFR_RNDZ); if (! mpfr_equal_p (x2, x0)) { printf ("Error in random_tests for prec=%d i=%d base=%d\n", prec, i, base); printf ("s0 = %s\ns1 = %s\ns2 = %s\n", s0, s1, s2); printf ("x0 = "); mpfr_dump (x0); printf ("x2 = "); mpfr_dump (x2); exit (1); } } mpfr_strtofr (x2, s2, NULL, base, MPFR_RNDA); if (! mpfr_equal_p (x2, x1)) { printf ("Error in random_tests for prec=%d i=%d base=%d\n", prec, i, base); printf ("s0 = %s\ns1 = %s\ns2 = %s\n", s0, s1, s2); printf ("x1 = "); mpfr_dump (x1); printf ("x2 = "); mpfr_dump (x2); exit (1); } } mpfr_clears (x0, x1, x2, (mpfr_ptr) 0); } } int main (int argc, char *argv[]) { tests_start_mpfr (); coverage (); check_special(); check_reftable (); check_parse (); check_overflow (); check_retval (); bug20081028 (); test20100310 (); bug20120814 (); bug20120829 (); bug20161217 (); bug20170308 (); bug20181127 (); random_tests (); tests_end_mpfr (); return 0; }