(root)/
mpfr-4.2.1/
tests/
tget_set_d128.c
       1  /* Test file for mpfr_set_decimal128 and mpfr_get_decimal128.
       2  
       3  Copyright 2018-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  /* Needed due to the test on MPFR_WANT_DECIMAL_FLOATS */
      24  #ifdef HAVE_CONFIG_H
      25  # include "config.h"
      26  #endif
      27  
      28  #ifdef MPFR_WANT_DECIMAL_FLOATS
      29  
      30  #include "mpfr-test.h"
      31  
      32  #ifndef DEC128_MAX
      33  # define DEC128_MAX 9.999999999999999999999999999999999E6144dl
      34  #endif
      35  
      36  static void
      37  print_decimal128 (_Decimal128 d)
      38  {
      39    if (DOUBLE_ISNAN (d))
      40      printf ("NaN");
      41    else if (d > DEC128_MAX)
      42      printf ("Inf");
      43    else if (d < -DEC128_MAX)
      44      printf ("-Inf");
      45    else if (d == 0)
      46      {
      47        printf ("%.1f", (double) d);
      48      }
      49    else /* regular number */
      50      {
      51        long e = 0;
      52        while (d < 1.dl)
      53          {
      54            d *= 10.dl;
      55            e --;
      56          }
      57        /* now d >= 1 */
      58        while (d > 10.dl)
      59          {
      60            d /= 10.dl;
      61            e ++;
      62          }
      63        /* now 1 <= d < 10 */
      64        printf ("%.33LfE%ld", (long double) d, e);
      65      }
      66    printf ("\n");
      67  }
      68  
      69  #define PRINT_ERR_MISC(V)                                   \
      70    do                                                        \
      71      {                                                       \
      72        printf ("Error in check_misc for %s.\n", V);          \
      73        printf ("  mpfr_get_decimal128() returned: ");        \
      74        print_decimal128 (d);                                 \
      75        printf ("  mpfr_set_decimal128() set x to: ");        \
      76        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);           \
      77        printf (" approx.\n    = ");                          \
      78        mpfr_dump (x);                                        \
      79        exit (1);                                             \
      80      }                                                       \
      81   while (0)
      82  
      83  static void
      84  test_set (void)
      85  {
      86    long v[] = { 1, -1, 2147483647, -2147483647 };
      87    mpfr_t x;
      88    mpfr_flags_t flags;
      89    int i, inex;
      90  
      91    mpfr_init2 (x, 53);
      92    for (i = 0; i < numberof (v); i++)
      93      {
      94        mpfr_clear_flags ();
      95        inex = mpfr_set_decimal128 (x, (_Decimal128) v[i], MPFR_RNDN);
      96        flags = __gmpfr_flags;
      97        if (mpfr_cmp_si (x, v[i]) != 0 || inex != 0 || flags != 0)
      98          {
      99            printf ("Error in test_set for i=%d\n", i);
     100            printf ("Expected %ld\n    with inex = 0 and flags =", v[i]);
     101            flags_out (0);
     102            printf ("Got      ");
     103            mpfr_dump (x);
     104            printf ("    with inex = %d and flags =", inex);
     105            flags_out (flags);
     106            exit (1);
     107          }
     108      }
     109    mpfr_clear (x);
     110  }
     111  
     112  static void
     113  powers_of_10 (void)
     114  {
     115    mpfr_t x1, x2;
     116    _Decimal128 d[2];
     117    int i, rnd;
     118    unsigned int neg;
     119  
     120    mpfr_inits2 (200, x1, x2, (mpfr_ptr) 0);
     121    for (i = 0, d[0] = 1, d[1] = 1; i < 150; i++, d[0] *= 10, d[1] /= 10)
     122      for (neg = 0; neg <= 3; neg++)
     123        RND_LOOP_NO_RNDF (rnd)
     124          {
     125            int inex1, inex2;
     126            mpfr_flags_t flags1, flags2;
     127            mpfr_rnd_t rx1;
     128            _Decimal128 dd;
     129  
     130            inex1 = mpfr_set_si (x1, (neg >> 1) ? -i : i, MPFR_RNDN);
     131            MPFR_ASSERTN (inex1 == 0);
     132  
     133            rx1 = (neg & 1) ?
     134              MPFR_INVERT_RND ((mpfr_rnd_t) rnd) : (mpfr_rnd_t) rnd;
     135            mpfr_clear_flags ();
     136            inex1 = mpfr_exp10 (x1, x1, rx1);
     137            flags1 = __gmpfr_flags;
     138  
     139            dd = d[neg >> 1];
     140  
     141            if (neg & 1)
     142              {
     143                MPFR_SET_NEG (x1);
     144                inex1 = -inex1;
     145                dd = -dd;
     146              }
     147  
     148            mpfr_clear_flags ();
     149            inex2 = mpfr_set_decimal128 (x2, dd, (mpfr_rnd_t) rnd);
     150            flags2 = __gmpfr_flags;
     151  
     152            if (!(mpfr_equal_p (x1, x2) &&
     153                  SAME_SIGN (inex1, inex2) &&
     154                  flags1 == flags2))
     155              {
     156                printf ("Error in powers_of_10 for i=%d, neg=%d, %s\n",
     157                        i, neg, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
     158                printf ("Expected ");
     159                mpfr_dump (x1);
     160                printf ("with inex = %d and flags =", inex1);
     161                flags_out (flags1);
     162                printf ("Got      ");
     163                mpfr_dump (x2);
     164                printf ("with inex = %d and flags =", inex2);
     165                flags_out (flags2);
     166                exit (1);
     167              }
     168          }
     169    mpfr_clears (x1, x2, (mpfr_ptr) 0);
     170  }
     171  
     172  static void
     173  check_misc (void)
     174  {
     175    mpfr_t  x, y;
     176    _Decimal128 d;
     177  
     178    mpfr_init2 (x, 123);
     179    mpfr_init2 (y, 123);
     180  
     181  #if !defined(MPFR_ERRDIVZERO)
     182    mpfr_set_nan (x);
     183    d = mpfr_get_decimal128 (x, MPFR_RNDZ);
     184    mpfr_set_ui (x, 1, MPFR_RNDZ);
     185    mpfr_set_decimal128 (x, d, MPFR_RNDZ);
     186    MPFR_ASSERTN (mpfr_nan_p (x));
     187  
     188    mpfr_set_inf (x, 1);
     189    d = mpfr_get_decimal128 (x, MPFR_RNDZ);
     190    mpfr_set_ui (x, 1, MPFR_RNDZ);
     191    mpfr_set_decimal128 (x, d, MPFR_RNDZ);
     192    if (! mpfr_inf_p (x) || MPFR_IS_NEG (x))
     193      PRINT_ERR_MISC ("+Inf");
     194  
     195    mpfr_set_inf (x, -1);
     196    d = mpfr_get_decimal128 (x, MPFR_RNDZ);
     197    mpfr_set_ui (x, 1, MPFR_RNDZ);
     198    mpfr_set_decimal128 (x, d, MPFR_RNDZ);
     199    if (! mpfr_inf_p (x) || MPFR_IS_POS (x))
     200      PRINT_ERR_MISC ("-Inf");
     201  #endif
     202  
     203    mpfr_set_ui (x, 0, MPFR_RNDZ);
     204    d = mpfr_get_decimal128 (x, MPFR_RNDZ);
     205    mpfr_set_ui (x, 1, MPFR_RNDZ);
     206    mpfr_set_decimal128 (x, d, MPFR_RNDZ);
     207    if (MPFR_NOTZERO (x) || MPFR_IS_NEG (x))
     208      PRINT_ERR_MISC ("+0");
     209  
     210    mpfr_set_ui (x, 0, MPFR_RNDZ);
     211    mpfr_neg (x, x, MPFR_RNDZ);
     212    d = mpfr_get_decimal128 (x, MPFR_RNDZ);
     213    mpfr_set_ui (x, 1, MPFR_RNDZ);
     214    mpfr_set_decimal128 (x, d, MPFR_RNDZ);
     215    if (MPFR_NOTZERO (x) || MPFR_IS_POS (x))
     216      PRINT_ERR_MISC ("-0");
     217  
     218    mpfr_set_ui (x, 1, MPFR_RNDZ);
     219    d = mpfr_get_decimal128 (x, MPFR_RNDZ);
     220    mpfr_set_ui (x, 0, MPFR_RNDZ);
     221    mpfr_set_decimal128 (x, d, MPFR_RNDZ);
     222    if (mpfr_cmp_ui (x, 1) != 0)
     223      PRINT_ERR_MISC ("+1");
     224  
     225    mpfr_set_si (x, -1, MPFR_RNDZ);
     226    d = mpfr_get_decimal128 (x, MPFR_RNDZ);
     227    mpfr_set_ui (x, 0, MPFR_RNDZ);
     228    mpfr_set_decimal128 (x, d, MPFR_RNDZ);
     229    if (mpfr_cmp_si (x, -1) != 0)
     230      PRINT_ERR_MISC ("-1");
     231  
     232    mpfr_set_ui (x, 2, MPFR_RNDZ);
     233    d = mpfr_get_decimal128 (x, MPFR_RNDZ);
     234    mpfr_set_ui (x, 0, MPFR_RNDZ);
     235    mpfr_set_decimal128 (x, d, MPFR_RNDZ);
     236    if (mpfr_cmp_ui (x, 2) != 0)
     237      PRINT_ERR_MISC ("2");
     238  
     239    mpfr_set_ui (x, 99, MPFR_RNDZ);
     240    d = mpfr_get_decimal128 (x, MPFR_RNDZ);
     241    mpfr_set_ui (x, 0, MPFR_RNDZ);
     242    mpfr_set_decimal128 (x, d, MPFR_RNDZ);
     243    if (mpfr_cmp_ui (x, 99) != 0)
     244      PRINT_ERR_MISC ("99");
     245  
     246    mpfr_set_str (x, "9999999999999999999999999999999999", 10, MPFR_RNDZ);
     247    mpfr_set (y, x, MPFR_RNDZ);
     248    d = mpfr_get_decimal128 (x, MPFR_RNDZ);
     249    mpfr_set_ui (x, 0, MPFR_RNDZ);
     250    mpfr_set_decimal128 (x, d, MPFR_RNDZ);
     251    if (! mpfr_equal_p (x, y))
     252      PRINT_ERR_MISC ("9999999999999999999999999999999999");
     253  
     254    /* smallest normal number */
     255    mpfr_set_str (x, "1E-6143", 10, MPFR_RNDU);
     256    mpfr_set (y, x, MPFR_RNDZ);
     257    d = mpfr_get_decimal128 (x, MPFR_RNDZ);
     258    mpfr_set_ui (x, 0, MPFR_RNDZ);
     259    mpfr_set_decimal128 (x, d, MPFR_RNDU);
     260    if (! mpfr_equal_p (x, y))
     261      PRINT_ERR_MISC ("1E-6143");
     262  
     263    /* smallest subnormal number */
     264    mpfr_set_str (x, "1E-6176", 10, MPFR_RNDU);
     265    mpfr_set (y, x, MPFR_RNDZ);
     266    d = mpfr_get_decimal128 (x, MPFR_RNDZ);
     267    mpfr_set_ui (x, 0, MPFR_RNDZ);
     268    mpfr_set_decimal128 (x, d, MPFR_RNDU);
     269    if (! mpfr_equal_p (x, y))
     270      PRINT_ERR_MISC ("1E-6176");
     271  
     272    /* exercise case e < -20517, i.e., x < 0.5*2^(-20517) */
     273    mpfr_set_ui_2exp (x, 1, -20518, MPFR_RNDN);
     274    mpfr_nextbelow (x);
     275    d = mpfr_get_decimal128 (x, MPFR_RNDZ);
     276    /* d should equal +0 */
     277    mpfr_set_decimal128 (x, d, MPFR_RNDN);
     278    MPFR_ASSERTN(mpfr_zero_p (x) && mpfr_signbit (x) == 0);
     279    /* check RNDA */
     280    mpfr_set_ui_2exp (x, 1, -20518, MPFR_RNDN);
     281    mpfr_nextbelow (x);
     282    d = mpfr_get_decimal128 (x, MPFR_RNDA);
     283    /* d should equal 1E-6176 */
     284    mpfr_set_decimal128 (x, d, MPFR_RNDN);
     285    mpfr_set_str (y, "1E-6176", 10, MPFR_RNDN);
     286    MPFR_ASSERTN(mpfr_equal_p (x, y));
     287    /* check negative number */
     288    mpfr_set_ui_2exp (x, 1, -20518, MPFR_RNDN);
     289    mpfr_nextbelow (x);
     290    mpfr_neg (x, x, MPFR_RNDN);
     291    d = mpfr_get_decimal128 (x, MPFR_RNDZ);
     292    /* d should equal -0 */
     293    mpfr_set_decimal128 (x, d, MPFR_RNDN);
     294    MPFR_ASSERTN(mpfr_zero_p (x) && mpfr_signbit (x) == 1);
     295  
     296    /* exercise case e10 < -6175 */
     297    mpfr_set_ui_2exp (x, 1, -20517, MPFR_RNDN);
     298    d = mpfr_get_decimal128 (x, MPFR_RNDZ);
     299    mpfr_set_decimal128 (x, d, MPFR_RNDN);
     300    MPFR_ASSERTN(mpfr_zero_p (x) && mpfr_signbit (x) == 0);
     301    mpfr_set_ui_2exp (x, 1, -20517, MPFR_RNDN);
     302    d = mpfr_get_decimal128 (x, MPFR_RNDU);
     303    mpfr_set_str (y, "1E-6176", 10, MPFR_RNDN);
     304    mpfr_set_decimal128 (x, d, MPFR_RNDN);
     305    MPFR_ASSERTN(mpfr_equal_p (x, y));
     306    mpfr_set_ui_2exp (x, 1, -20517, MPFR_RNDN);
     307    /* 2^(-20517) = 5.85570193228610e-6177 thus should be rounded to 1E-6176 */
     308    d = mpfr_get_decimal128 (x, MPFR_RNDN);
     309    mpfr_set_str (y, "1E-6176", 10, MPFR_RNDN);
     310    mpfr_set_decimal128 (x, d, MPFR_RNDN);
     311    MPFR_ASSERTN(mpfr_equal_p (x, y));
     312  
     313    /* subnormal number with exponent change when we round back
     314       from 34 digits to 1 digit */
     315    mpfr_set_str (x, "9.9E-6176", 10, MPFR_RNDN);
     316    d = mpfr_get_decimal128 (x, MPFR_RNDU); /* should be 1E-6175 */
     317    mpfr_set_ui (x, 0, MPFR_RNDZ);
     318    mpfr_set_decimal128 (x, d, MPFR_RNDU);
     319    mpfr_set_str (y, "1E-6175", 10, MPFR_RNDN);
     320    if (! mpfr_equal_p (x, y))
     321      PRINT_ERR_MISC ("9.9E-6176");
     322  
     323    /* largest number */
     324    mpfr_set_str (x, "9.999999999999999999999999999999999E6144", 10, MPFR_RNDZ);
     325    mpfr_set (y, x, MPFR_RNDZ);
     326    d = mpfr_get_decimal128 (x, MPFR_RNDU);
     327    if (d == DEC128_MAX)
     328      {
     329        mpfr_set_ui (x, 0, MPFR_RNDZ);
     330        mpfr_set_decimal128 (x, d, MPFR_RNDZ);
     331        if (! mpfr_equal_p (x, y))
     332          PRINT_ERR_MISC ("DEC128_MAX");
     333      }
     334    else
     335      {
     336        printf ("Error in check_misc for DEC128_MAX.\n");
     337        printf ("  mpfr_get_decimal128() returned: ");
     338        print_decimal128 (d);
     339        exit (1);
     340      }
     341  
     342    mpfr_set_str (x, "-9.999999999999999999999999999999999E6144", 10, MPFR_RNDZ);
     343    mpfr_set (y, x, MPFR_RNDZ);
     344    d = mpfr_get_decimal128 (x, MPFR_RNDA);
     345    if (d == -DEC128_MAX)
     346      {
     347        mpfr_set_ui (x, 0, MPFR_RNDZ);
     348        mpfr_set_decimal128 (x, d, MPFR_RNDZ);
     349        if (! mpfr_equal_p (x, y))
     350          PRINT_ERR_MISC ("-DEC128_MAX");
     351      }
     352    else
     353      {
     354        printf ("Error in check_misc for -DEC128_MAX.\n");
     355        printf ("  mpfr_get_decimal128() returned: ");
     356        print_decimal128 (d);
     357        exit (1);
     358      }
     359  
     360    /* exercise |x| > DEC128_MAX */
     361    mpfr_set_str (x, "10E6144", 10, MPFR_RNDU);
     362    d = mpfr_get_decimal128 (x, MPFR_RNDZ);
     363    MPFR_ASSERTN(d == DEC128_MAX);
     364    mpfr_set_str (x, "-10E6144", 10, MPFR_RNDU);
     365    d = mpfr_get_decimal128 (x, MPFR_RNDZ);
     366    MPFR_ASSERTN(d == -DEC128_MAX);
     367  
     368    mpfr_set_prec (x, 53);
     369    mpfr_set_prec (y, 53);
     370  
     371    /* largest number */
     372    mpfr_set_str (x, "9.999999999999999999999999999999999E6144", 10, MPFR_RNDZ);
     373    d = mpfr_get_decimal128 (x, MPFR_RNDZ);
     374    mpfr_set_decimal128 (y, d, MPFR_RNDU);
     375    if (! mpfr_equal_p (x, y))
     376      PRINT_ERR_MISC ("DEC128_MAX (2)");
     377  
     378    /* since 1+ceil(109*log(2)/log(10)) = 34, the 109-bit value x, when
     379       converted to a 34-digit decimal d, gives back x when converted back to
     380       binary */
     381    mpfr_set_prec (x, 109);
     382    mpfr_set_prec (y, 109);
     383    mpfr_set_str (x, "1E1793", 10, MPFR_RNDN);
     384    d = mpfr_get_decimal128 (x, MPFR_RNDN);
     385    mpfr_set_ui (x, 0, MPFR_RNDZ);
     386    mpfr_set_decimal128 (x, d, MPFR_RNDN);
     387    mpfr_set_str (y, "1E1793", 10, MPFR_RNDN);
     388    if (! mpfr_equal_p (x, y))
     389      PRINT_ERR_MISC ("1E1793");
     390  
     391    mpfr_set_str (x, "2E4095", 10, MPFR_RNDN);
     392    d = mpfr_get_decimal128 (x, MPFR_RNDN);
     393    mpfr_set_ui (x, 0, MPFR_RNDZ);
     394    mpfr_set_decimal128 (x, d, MPFR_RNDN);
     395    mpfr_set_str (y, "2E4095", 10, MPFR_RNDN);
     396    if (! mpfr_equal_p (x, y))
     397      PRINT_ERR_MISC ("2E4095");
     398  
     399    mpfr_set_str (x, "2E-4096", 10, MPFR_RNDN);
     400    d = mpfr_get_decimal128 (x, MPFR_RNDN);
     401    mpfr_set_ui (x, 0, MPFR_RNDZ);
     402    mpfr_set_decimal128 (x, d, MPFR_RNDN);
     403    mpfr_set_str (y, "2E-4096", 10, MPFR_RNDN);
     404    if (! mpfr_equal_p (x, y))
     405      PRINT_ERR_MISC ("2E-4096");
     406  
     407    mpfr_set_str (x, "2E-6110", 10, MPFR_RNDN);
     408    d = mpfr_get_decimal128 (x, MPFR_RNDN);
     409    mpfr_set_ui (x, 0, MPFR_RNDZ);
     410    mpfr_set_decimal128 (x, d, MPFR_RNDN);
     411    mpfr_set_str (y, "2E-6110", 10, MPFR_RNDN);
     412    if (! mpfr_equal_p (x, y))
     413      PRINT_ERR_MISC ("2E-6110");
     414  
     415    /* case where EXP(x) > 20414, thus outside the decimal128 range */
     416    mpfr_set_ui_2exp (x, 1, 20414, MPFR_RNDN);
     417    d = mpfr_get_decimal128 (x, MPFR_RNDZ);
     418    MPFR_ASSERTN(d == DEC128_MAX);
     419    d = mpfr_get_decimal128 (x, MPFR_RNDA);
     420    MPFR_ASSERTN(d > DEC128_MAX); /* implies d = +Inf */
     421    mpfr_set_si_2exp (x, -1, 20414, MPFR_RNDN);
     422    d = mpfr_get_decimal128 (x, MPFR_RNDZ);
     423    MPFR_ASSERTN(d == -DEC128_MAX);
     424    d = mpfr_get_decimal128 (x, MPFR_RNDA);
     425    MPFR_ASSERTN(d < -DEC128_MAX); /* implies d = -Inf */
     426  
     427    /* case where EXP(x) = 20414, at the limit of the decimal128 range */
     428    mpfr_set_ui_2exp (x, 3, 20412, MPFR_RNDN); /* 3*2^20412 > 9.999...E6144 */
     429    d = mpfr_get_decimal128 (x, MPFR_RNDN);
     430    MPFR_ASSERTN(d > DEC128_MAX); /* implies d = +Inf */
     431    mpfr_set_si_2exp (x, -3, 20412, MPFR_RNDN);
     432    d = mpfr_get_decimal128 (x, MPFR_RNDN);
     433    MPFR_ASSERTN(d < -DEC128_MAX); /* implies d = -Inf */
     434  
     435    {
     436      unsigned long i;
     437      for (i = 1; i < 1000; i++)
     438        {
     439          mpfr_set_ui_2exp (x, i, 20403, MPFR_RNDN);
     440          d = mpfr_get_decimal128 (x, MPFR_RNDN);
     441          mpfr_set_decimal128 (x, d, MPFR_RNDN);
     442          MPFR_ASSERTN(mpfr_cmp_ui_2exp (x, i, 20403) == 0);
     443        }
     444    }
     445  
     446    mpfr_clear (x);
     447    mpfr_clear (y);
     448  }
     449  
     450  static void
     451  noncanonical (void)
     452  {
     453    /* The code below assumes BID. */
     454  #if HAVE_DECIMAL128_IEEE && defined(DECIMAL_BID_FORMAT)
     455    union ieee_decimal128 x;
     456  
     457    MPFR_ASSERTN (sizeof (x) == 16);
     458    /* produce a non-canonical decimal128 with Gh >= 24 */
     459    x.d128 = 1;
     460    /* if BID, we have sig=0, comb=49408, t0=t1=t2=0, t3=1 */
     461    if (x.s.sig == 0 && x.s.comb == 49408 && x.s.t0 == 0 && x.s.t1 == 0 &&
     462        x.s.t2 == 0 && x.s.t3 == 1)
     463      {
     464        /* The volatile below avoids _Decimal128 constant propagation, which is
     465           buggy for non-canonical encoding in various GCC versions on the x86
     466           and x86_64 targets: failure in the second test below ("Error 2")
     467           with gcc (Debian 20190820-1) 10.0.0 20190820 (experimental)
     468           [trunk revision 274744]. The MPFR test was not failing with previous
     469           GCC versions, not even with gcc (Debian 20190719-1) 10.0.0 20190718
     470           (experimental) [trunk revision 273586] (contrary to the similar test
     471           in tget_set_d64.c). More information at:
     472           https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91226
     473        */
     474        volatile _Decimal128 d = 9999999999999999999999999999999999.dl;
     475        mpfr_t y;
     476  
     477        x.s.comb = 98560; /* force Gh >= 24 thus a non-canonical number
     478                             (significand >= 2^113 > 20^34-1) */
     479        mpfr_init2 (y, 113);
     480        mpfr_set_decimal128 (y, x.d128, MPFR_RNDN);
     481        if (MPFR_NOTZERO (y) || MPFR_IS_NEG (y))
     482          {
     483            int i;
     484            printf ("Error 1 in noncanonical on");
     485            for (i = 0; i < 16; i++)
     486              printf (" %02X", ((unsigned char *)&x)[i]);
     487            printf ("\nExpected +0, got:\n");
     488            mpfr_dump (y);
     489            exit (1);
     490          }
     491  
     492        /* now construct a case Gh < 24, but where the significand exceeds
     493           10^34-1 */
     494        x.d128 = d;
     495        /* should give sig=0, comb=49415, t0=11529, t1=3199043520,
     496           t2=932023907, t3=4294967295 */
     497        x.s.t3 ++; /* should give 0 */
     498        x.s.t2 += (x.s.t3 == 0);
     499        /* now the significand is 10^34 */
     500        mpfr_set_decimal128 (y, x.d128, MPFR_RNDN);
     501        if (MPFR_NOTZERO (y) || MPFR_IS_NEG (y))
     502          {
     503            int i;
     504            printf ("Error 2 in noncanonical on");
     505            for (i = 0; i < 16; i++)
     506              printf (" %02X", ((unsigned char *)&x)[i]);
     507            printf ("\nExpected +0, got:\n");
     508            mpfr_dump (y);
     509            exit (1);
     510          }
     511  
     512        mpfr_clear (y);
     513      }
     514    else
     515      printf ("Warning! Unexpected value of x in noncanonical.\n");
     516  #endif
     517  }
     518  
     519  /* generate random sequences of 16 bytes and interpret them as _Decimal128 */
     520  static void
     521  check_random_bytes (void)
     522  {
     523    union {
     524      _Decimal128 d;
     525      unsigned char c[16];
     526    } x;
     527    int i;
     528    mpfr_t y;
     529    _Decimal128 e;
     530  
     531    mpfr_init2 (y, 114); /* 114 = 1 + ceil(34*log(10)/log(2)), thus ensures
     532                           that if a decimal128 number is converted to a 114-bit
     533                           value and back, we should get the same value */
     534    for (i = 0; i < 100000; i++)
     535      {
     536        int j;
     537        for (j = 0; j < 16; j++)
     538          x.c[j] = randlimb () & 255;
     539        mpfr_set_decimal128 (y, x.d, MPFR_RNDN);
     540        e = mpfr_get_decimal128 (y, MPFR_RNDN);
     541        if (!mpfr_nan_p (y))
     542          if (x.d != e)
     543            {
     544              printf ("check_random_bytes failed\n");
     545              printf ("x.d="); print_decimal128 (x.d);
     546              printf ("y="); mpfr_dump (y);
     547              printf ("e="); print_decimal128 (e);
     548              exit (1);
     549            }
     550      }
     551    mpfr_clear (y);
     552  }
     553  
     554  int
     555  main (int argc, char *argv[])
     556  {
     557    int verbose = argc > 1;
     558  
     559    tests_start_mpfr ();
     560    mpfr_test_init ();
     561  
     562    if (verbose)
     563      {
     564  #ifdef DECIMAL_DPD_FORMAT
     565        printf ("Using DPD encoding\n");
     566  #endif
     567  #ifdef DECIMAL_BID_FORMAT
     568        printf ("Using BID encoding\n");
     569  #endif
     570      }
     571  
     572  #if !defined(MPFR_ERRDIVZERO)
     573    check_random_bytes ();
     574  #endif
     575    test_set ();
     576    powers_of_10 ();
     577  #if !defined(MPFR_ERRDIVZERO)
     578    check_misc ();
     579  #endif
     580    noncanonical ();
     581  
     582    tests_end_mpfr ();
     583    return 0;
     584  }
     585  
     586  #else /* MPFR_WANT_DECIMAL_FLOATS */
     587  
     588  int
     589  main (void)
     590  {
     591    return 77;
     592  }
     593  
     594  #endif /* MPFR_WANT_DECIMAL_FLOATS */