(root)/
mpfr-4.2.1/
tests/
tget_set_d64.c
       1  /* Test file for mpfr_get_decimal64 and mpfr_set_decimal64.
       2  
       3  Copyright 2006-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 DEC64_MAX
      33  # define DEC64_MAX 9.999999999999999E384dd
      34  #endif
      35  
      36  #if _MPFR_IEEE_FLOATS
      37  static void
      38  print_decimal64 (_Decimal64 d)
      39  {
      40    union mpfr_ieee_double_extract x;
      41    union ieee_double_decimal64 y;
      42    unsigned int Gh, i;
      43  
      44    y.d64 = d;
      45    x.d = y.d;
      46    Gh = x.s.exp >> 6;
      47    printf ("|%d%d%d%d%d%d", x.s.sig, Gh >> 4, (Gh >> 3) & 1,
      48            (Gh >> 2) & 1, (Gh >> 1) & 1, Gh & 1);
      49    printf ("%d%d%d%d%d%d", (x.s.exp >> 5) & 1, (x.s.exp >> 4) & 1,
      50            (x.s.exp >> 3) & 1, (x.s.exp >> 2) & 1, (x.s.exp >> 1) & 1,
      51            x.s.exp & 1);
      52    for (i = 20; i > 0; i--)
      53      printf ("%d", (x.s.manh >> (i - 1)) & 1);
      54    for (i = 32; i > 0; i--)
      55      printf ("%d", (x.s.manl >> (i - 1)) & 1);
      56    printf ("|\n");
      57  }
      58  #else
      59  /* Portable version, assuming long double has at least 55 bits.
      60     Note: __STDC_WANT_IEC_60559_DFP_EXT__ or __STDC_WANT_DEC_FP__
      61     might allow to use printf("%.15De\n", d) */
      62  static void
      63  print_decimal64 (_Decimal64 d)
      64  {
      65    printf ("%.15Le\n", (long double) d);
      66  }
      67  #endif /* _MPFR_IEEE_FLOATS */
      68  
      69  #define PRINT_ERR_MISC(V)                                   \
      70    do                                                        \
      71      {                                                       \
      72        printf ("Error in check_misc for %s.\n", V);          \
      73        printf ("  mpfr_get_decimal64() returned: ");         \
      74        print_decimal64 (d);                                  \
      75        printf ("  mpfr_set_decimal64() 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  check_misc (void)
      85  {
      86    mpfr_t  x, y;
      87    _Decimal64 d;
      88  
      89    mpfr_init2 (x, 123);
      90    mpfr_init2 (y, 123);
      91  
      92  #if !defined(MPFR_ERRDIVZERO)
      93    mpfr_set_nan (x);
      94    d = mpfr_get_decimal64 (x, MPFR_RNDZ);
      95    mpfr_set_ui (x, 1, MPFR_RNDZ);
      96    mpfr_set_decimal64 (x, d, MPFR_RNDZ);
      97    MPFR_ASSERTN (mpfr_nan_p (x));
      98  
      99    mpfr_set_inf (x, 1);
     100    d = mpfr_get_decimal64 (x, MPFR_RNDZ);
     101    mpfr_set_ui (x, 1, MPFR_RNDZ);
     102    mpfr_set_decimal64 (x, d, MPFR_RNDZ);
     103    if (! mpfr_inf_p (x) || MPFR_IS_NEG (x))
     104      PRINT_ERR_MISC ("+Inf");
     105  
     106    mpfr_set_inf (x, -1);
     107    d = mpfr_get_decimal64 (x, MPFR_RNDZ);
     108    mpfr_set_ui (x, 1, MPFR_RNDZ);
     109    mpfr_set_decimal64 (x, d, MPFR_RNDZ);
     110    if (! mpfr_inf_p (x) || MPFR_IS_POS (x))
     111      PRINT_ERR_MISC ("-Inf");
     112  #endif
     113  
     114    mpfr_set_ui (x, 0, MPFR_RNDZ);
     115    d = mpfr_get_decimal64 (x, MPFR_RNDZ);
     116    mpfr_set_ui (x, 1, MPFR_RNDZ);
     117    mpfr_set_decimal64 (x, d, MPFR_RNDZ);
     118    if (MPFR_NOTZERO (x) || MPFR_IS_NEG (x))
     119      PRINT_ERR_MISC ("+0");
     120  
     121    mpfr_set_ui (x, 0, MPFR_RNDZ);
     122    mpfr_neg (x, x, MPFR_RNDZ);
     123    d = mpfr_get_decimal64 (x, MPFR_RNDZ);
     124    mpfr_set_ui (x, 1, MPFR_RNDZ);
     125    mpfr_set_decimal64 (x, d, MPFR_RNDZ);
     126    if (MPFR_NOTZERO (x) || MPFR_IS_POS (x))
     127      PRINT_ERR_MISC ("-0");
     128  
     129    mpfr_set_ui (x, 1, MPFR_RNDZ);
     130    d = mpfr_get_decimal64 (x, MPFR_RNDZ);
     131    mpfr_set_ui (x, 0, MPFR_RNDZ);
     132    mpfr_set_decimal64 (x, d, MPFR_RNDZ);
     133    if (mpfr_cmp_ui (x, 1) != 0)
     134      PRINT_ERR_MISC ("+1");
     135  
     136    mpfr_set_si (x, -1, MPFR_RNDZ);
     137    d = mpfr_get_decimal64 (x, MPFR_RNDZ);
     138    mpfr_set_ui (x, 0, MPFR_RNDZ);
     139    mpfr_set_decimal64 (x, d, MPFR_RNDZ);
     140    if (mpfr_cmp_si (x, -1) != 0)
     141      PRINT_ERR_MISC ("-1");
     142  
     143    mpfr_set_ui (x, 2, MPFR_RNDZ);
     144    d = mpfr_get_decimal64 (x, MPFR_RNDZ);
     145    mpfr_set_ui (x, 0, MPFR_RNDZ);
     146    mpfr_set_decimal64 (x, d, MPFR_RNDZ);
     147    if (mpfr_cmp_ui (x, 2) != 0)
     148      PRINT_ERR_MISC ("2");
     149  
     150    mpfr_set_ui (x, 99, MPFR_RNDZ);
     151    d = mpfr_get_decimal64 (x, MPFR_RNDZ);
     152    mpfr_set_ui (x, 0, MPFR_RNDZ);
     153    mpfr_set_decimal64 (x, d, MPFR_RNDZ);
     154    if (mpfr_cmp_ui (x, 99) != 0)
     155      PRINT_ERR_MISC ("99");
     156  
     157    mpfr_set_str (x, "9999999999999999", 10, MPFR_RNDZ);
     158    mpfr_set (y, x, MPFR_RNDZ);
     159    d = mpfr_get_decimal64 (x, MPFR_RNDZ);
     160    mpfr_set_ui (x, 0, MPFR_RNDZ);
     161    mpfr_set_decimal64 (x, d, MPFR_RNDZ);
     162    if (! mpfr_equal_p (x, y))
     163      PRINT_ERR_MISC ("9999999999999999");
     164  
     165    /* smallest normal number */
     166    mpfr_set_str (x, "1E-383", 10, MPFR_RNDU);
     167    mpfr_set (y, x, MPFR_RNDZ);
     168    d = mpfr_get_decimal64 (x, MPFR_RNDZ);
     169    mpfr_set_ui (x, 0, MPFR_RNDZ);
     170    mpfr_set_decimal64 (x, d, MPFR_RNDU);
     171    if (! mpfr_equal_p (x, y))
     172      PRINT_ERR_MISC ("1E-383");
     173  
     174    /* smallest subnormal number */
     175    mpfr_set_str (x, "1E-398", 10, MPFR_RNDU);
     176    mpfr_set (y, x, MPFR_RNDZ);
     177    d = mpfr_get_decimal64 (x, MPFR_RNDZ);
     178    mpfr_set_ui (x, 0, MPFR_RNDZ);
     179    mpfr_set_decimal64 (x, d, MPFR_RNDU);
     180    if (! mpfr_equal_p (x, y))
     181      PRINT_ERR_MISC ("1E-398");
     182  
     183    /* exercise case e < -1323, i.e., x < 0.5*2^(-1323) */
     184    mpfr_set_ui_2exp (x, 1, -1324, MPFR_RNDN);
     185    mpfr_nextbelow (x);
     186    d = mpfr_get_decimal64 (x, MPFR_RNDZ);
     187    /* d should equal +0 */
     188    mpfr_set_decimal64 (x, d, MPFR_RNDN);
     189    MPFR_ASSERTN(mpfr_zero_p (x) && mpfr_signbit (x) == 0);
     190    /* check RNDA */
     191    mpfr_set_ui_2exp (x, 1, -1324, MPFR_RNDN);
     192    mpfr_nextbelow (x);
     193    d = mpfr_get_decimal64 (x, MPFR_RNDA);
     194    /* d should equal 1E-398 */
     195    mpfr_set_decimal64 (x, d, MPFR_RNDN);
     196    mpfr_set_str (y, "1E-398", 10, MPFR_RNDN);
     197    MPFR_ASSERTN(mpfr_equal_p (x, y));
     198    /* check negative number */
     199    mpfr_set_ui_2exp (x, 1, -1324, MPFR_RNDN);
     200    mpfr_nextbelow (x);
     201    mpfr_neg (x, x, MPFR_RNDN);
     202    d = mpfr_get_decimal64 (x, MPFR_RNDZ);
     203    /* d should equal -0 */
     204    mpfr_set_decimal64 (x, d, MPFR_RNDN);
     205    MPFR_ASSERTN(mpfr_zero_p (x) && mpfr_signbit (x) == 1);
     206  
     207    /* exercise case e10 < -397 */
     208    mpfr_set_ui_2exp (x, 1, -1323, MPFR_RNDN);
     209    d = mpfr_get_decimal64 (x, MPFR_RNDZ);
     210    mpfr_set_decimal64 (x, d, MPFR_RNDN);
     211    MPFR_ASSERTN(mpfr_zero_p (x) && mpfr_signbit (x) == 0);
     212    mpfr_set_ui_2exp (x, 1, -1323, MPFR_RNDN);
     213    d = mpfr_get_decimal64 (x, MPFR_RNDU);
     214    mpfr_set_str (y, "1E-398", 10, MPFR_RNDN);
     215    mpfr_set_decimal64 (x, d, MPFR_RNDN);
     216    MPFR_ASSERTN(mpfr_equal_p (x, y));
     217    mpfr_set_ui_2exp (x, 1, -1323, MPFR_RNDN);
     218    /* 2^(-1323) = 5.46154776930125e-399 thus should be rounded to 1E-398 */
     219    d = mpfr_get_decimal64 (x, MPFR_RNDN);
     220    mpfr_set_str (y, "1E-398", 10, MPFR_RNDN);
     221    mpfr_set_decimal64 (x, d, MPFR_RNDN);
     222    MPFR_ASSERTN(mpfr_equal_p (x, y));
     223  
     224    /* subnormal number with exponent change when we round back
     225       from 16 digits to 1 digit */
     226    mpfr_set_str (x, "9.9E-398", 10, MPFR_RNDN);
     227    d = mpfr_get_decimal64 (x, MPFR_RNDU); /* should be 1E-397 */
     228    mpfr_set_ui (x, 0, MPFR_RNDZ);
     229    mpfr_set_decimal64 (x, d, MPFR_RNDD);
     230    mpfr_set_str (y, "1E-397", 10, MPFR_RNDN);
     231    if (! mpfr_equal_p (x, y))
     232      PRINT_ERR_MISC ("9.9E-398");
     233  
     234    /* largest number */
     235    mpfr_set_str (x, "9.999999999999999E384", 10, MPFR_RNDZ);
     236    mpfr_set (y, x, MPFR_RNDZ);
     237    d = mpfr_get_decimal64 (x, MPFR_RNDU);
     238    if (d == DEC64_MAX)
     239      {
     240        mpfr_set_ui (x, 0, MPFR_RNDZ);
     241        mpfr_set_decimal64 (x, d, MPFR_RNDZ);
     242        if (! mpfr_equal_p (x, y))
     243          PRINT_ERR_MISC ("DEC64_MAX");
     244      }
     245    else
     246      {
     247        printf ("Error in check_misc for DEC64_MAX.\n");
     248        printf ("  mpfr_get_decimal64() returned: ");
     249        print_decimal64 (d);
     250        exit (1);
     251      }
     252  
     253    mpfr_set_str (x, "-9.999999999999999E384", 10, MPFR_RNDZ);
     254    mpfr_set (y, x, MPFR_RNDZ);
     255    d = mpfr_get_decimal64 (x, MPFR_RNDA);
     256    if (d == -DEC64_MAX)
     257      {
     258        mpfr_set_ui (x, 0, MPFR_RNDZ);
     259        mpfr_set_decimal64 (x, d, MPFR_RNDZ);
     260        if (! mpfr_equal_p (x, y))
     261          PRINT_ERR_MISC ("-DEC64_MAX");
     262      }
     263    else
     264      {
     265        printf ("Error in check_misc for -DEC64_MAX.\n");
     266        printf ("  mpfr_get_decimal64() returned: ");
     267        print_decimal64 (d);
     268        exit (1);
     269      }
     270  
     271    mpfr_set_prec (x, 53);
     272    mpfr_set_prec (y, 53);
     273  
     274    /* largest number */
     275    mpfr_set_str (x, "9.999999999999999E384", 10, MPFR_RNDZ);
     276    d = mpfr_get_decimal64 (x, MPFR_RNDZ);
     277    mpfr_set_decimal64 (y, d, MPFR_RNDU);
     278    if (! mpfr_equal_p (x, y))
     279      PRINT_ERR_MISC ("DEC64_MAX (2)");
     280  
     281    mpfr_clear (x);
     282    mpfr_clear (y);
     283  }
     284  
     285  static void
     286  check_random (void)
     287  {
     288    mpfr_t  x, y;
     289    _Decimal64 d;
     290    int i;
     291  
     292    mpfr_init2 (x, 49);
     293    mpfr_init2 (y, 49);
     294  
     295    for (i = 0; i < 100000; i++)
     296      {
     297        mpfr_urandomb (x, RANDS); /* 0 <= x < 1 */
     298        /* the normal decimal64 range contains [2^(-1272), 2^1278] */
     299        mpfr_mul_2si (x, x, (i % 2550) - 1272, MPFR_RNDN);
     300        if (mpfr_get_exp (x) <= -1272)
     301          mpfr_mul_2ui (x, x, -1271 - mpfr_get_exp (x), MPFR_RNDN);
     302        d = mpfr_get_decimal64 (x, MPFR_RNDN);
     303        mpfr_set_decimal64 (y, d, MPFR_RNDN);
     304        if (! mpfr_equal_p (x, y))
     305          {
     306            printf ("Error:\n");
     307            printf ("x="); mpfr_dump (x);
     308            printf ("d="); print_decimal64 (d);
     309            printf ("y="); mpfr_dump (y);
     310            exit (1);
     311          }
     312      }
     313  
     314    mpfr_clear (x);
     315    mpfr_clear (y);
     316  }
     317  
     318  /* check with native decimal formats */
     319  static void
     320  check_native (void)
     321  {
     322    mpfr_t x;
     323    _Decimal64 d;
     324  
     325    mpfr_init2 (x, 53);
     326  
     327    /* check important constants are correctly converted */
     328    mpfr_set_ui (x, 17, MPFR_RNDN);
     329    d = mpfr_get_decimal64 (x, MPFR_RNDN);
     330    MPFR_ASSERTN(d == 17.dd);
     331  
     332    mpfr_set_ui (x, 42, MPFR_RNDN);
     333    d = mpfr_get_decimal64 (x, MPFR_RNDN);
     334    MPFR_ASSERTN(d == 42.dd);
     335  
     336    mpfr_set_decimal64 (x, 17.dd, MPFR_RNDN);
     337    MPFR_ASSERTN(mpfr_cmp_ui (x, 17) == 0);
     338  
     339    mpfr_set_decimal64 (x, 17.0dd, MPFR_RNDN);
     340    MPFR_ASSERTN(mpfr_cmp_ui (x, 17) == 0);
     341  
     342    mpfr_set_decimal64 (x, 42.dd, MPFR_RNDN);
     343    MPFR_ASSERTN(mpfr_cmp_ui (x, 42) == 0);
     344  
     345    mpfr_set_decimal64 (x, 42.0dd, MPFR_RNDN);
     346    MPFR_ASSERTN(mpfr_cmp_ui (x, 42) == 0);
     347  
     348    mpfr_clear (x);
     349  }
     350  
     351  static void
     352  check_overflow (void)
     353  {
     354    mpfr_t x;
     355    int err = 0, neg, rnd;
     356  
     357    mpfr_init2 (x, 96);
     358    for (neg = 0; neg < 2; neg++)
     359      RND_LOOP (rnd)
     360        {
     361          _Decimal64 d, e;
     362          mpfr_rnd_t r = (mpfr_rnd_t) rnd;
     363          int sign = neg ? -1 : 1;
     364  
     365          e = sign * (MPFR_IS_LIKE_RNDZ (r, neg) ? 1 : 2) * DEC64_MAX;
     366          /* This tests the binary exponent e > 1279 case of get_d64.c */
     367          mpfr_set_si_2exp (x, sign, 9999, MPFR_RNDN);
     368          d = mpfr_get_decimal64 (x, r);
     369          if (d != e)
     370            {
     371              printf ("Error 1 in check_overflow for %s, %s\n",
     372                      neg ? "negative" : "positive",
     373                      mpfr_print_rnd_mode (r));
     374              err = 1;
     375            }
     376          /* This tests the decimal exponent e > 385 case of get_d64.c */
     377          mpfr_set_si_2exp (x, sign * 31, 1274, MPFR_RNDN);
     378          d = mpfr_get_decimal64 (x, r);
     379          if (d != e)
     380            {
     381              printf ("Error 2 in check_overflow for %s, %s\n",
     382                      neg ? "negative" : "positive",
     383                      mpfr_print_rnd_mode (r));
     384              err = 1;
     385            }
     386          /* This tests the last else (-382 <= e <= 385) of get_d64.c */
     387          mpfr_set_decimal64 (x, e, MPFR_RNDA);
     388          d = mpfr_get_decimal64 (x, r);
     389          if (d != e)
     390            {
     391              printf ("Error 3 in check_overflow for %s, %s\n",
     392                      neg ? "negative" : "positive",
     393                      mpfr_print_rnd_mode (r));
     394              err = 1;
     395            }
     396        }
     397    mpfr_clear (x);
     398    if (err)
     399      exit (1);
     400  }
     401  
     402  static void
     403  check_tiny (void)
     404  {
     405    mpfr_t x;
     406    _Decimal64 d;
     407  
     408    /* If 0.5E-398 < |x| < 1E-398 (smallest subnormal), x should round
     409       to +/- 1E-398 in MPFR_RNDN. Note: the midpoint 0.5E-398 between
     410       0 and 1E-398 is not a representable binary number, so that there
     411       are no tests for it. */
     412    mpfr_init2 (x, 128);
     413    mpfr_set_str (x, "1E-398", 10, MPFR_RNDZ);
     414    d = mpfr_get_decimal64 (x, MPFR_RNDN);
     415    MPFR_ASSERTN (d == 1.0E-398dd);
     416    mpfr_neg (x, x, MPFR_RNDN);
     417    d = mpfr_get_decimal64 (x, MPFR_RNDN);
     418    MPFR_ASSERTN (d == -1.0E-398dd);
     419    mpfr_set_str (x, "0.5E-398", 10, MPFR_RNDU);
     420    d = mpfr_get_decimal64 (x, MPFR_RNDN);
     421    MPFR_ASSERTN (d == 1.0E-398dd);
     422    mpfr_neg (x, x, MPFR_RNDN);
     423    d = mpfr_get_decimal64 (x, MPFR_RNDN);
     424    MPFR_ASSERTN (d == -1.0E-398dd);
     425    mpfr_clear (x);
     426  }
     427  
     428  static void
     429  powers_of_10 (void)
     430  {
     431    mpfr_t x1, x2;
     432    _Decimal64 d[2];
     433    int i, rnd;
     434    unsigned int neg;
     435  
     436    mpfr_inits2 (200, x1, x2, (mpfr_ptr) 0);
     437    for (i = 0, d[0] = 1, d[1] = 1; i < 150; i++, d[0] *= 10, d[1] /= 10)
     438      for (neg = 0; neg <= 3; neg++)
     439        RND_LOOP_NO_RNDF (rnd)
     440          {
     441            int inex1, inex2;
     442            mpfr_flags_t flags1, flags2;
     443            mpfr_rnd_t rx1;
     444            _Decimal64 dd;
     445  
     446            inex1 = mpfr_set_si (x1, (neg >> 1) ? -i : i, MPFR_RNDN);
     447            MPFR_ASSERTN (inex1 == 0);
     448  
     449            rx1 = (neg & 1) ?
     450              MPFR_INVERT_RND ((mpfr_rnd_t) rnd) : (mpfr_rnd_t) rnd;
     451            mpfr_clear_flags ();
     452            inex1 = mpfr_exp10 (x1, x1, rx1);
     453            flags1 = __gmpfr_flags;
     454  
     455            dd = d[neg >> 1];
     456  
     457            if (neg & 1)
     458              {
     459                MPFR_SET_NEG (x1);
     460                inex1 = -inex1;
     461                dd = -dd;
     462              }
     463  
     464            mpfr_clear_flags ();
     465            inex2 = mpfr_set_decimal64 (x2, dd, (mpfr_rnd_t) rnd);
     466            flags2 = __gmpfr_flags;
     467  
     468            if (!(mpfr_equal_p (x1, x2) &&
     469                  SAME_SIGN (inex1, inex2) &&
     470                  flags1 == flags2))
     471              {
     472                printf ("Error in powers_of_10 for i=%d, neg=%d, %s\n",
     473                        i, neg, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
     474                printf ("Expected ");
     475                mpfr_dump (x1);
     476                printf ("with inex = %d and flags =", inex1);
     477                flags_out (flags1);
     478                printf ("Got      ");
     479                mpfr_dump (x2);
     480                printf ("with inex = %d and flags =", inex2);
     481                flags_out (flags2);
     482                exit (1);
     483              }
     484          }
     485    mpfr_clears (x1, x2, (mpfr_ptr) 0);
     486  }
     487  
     488  static void
     489  noncanonical (void)
     490  {
     491    /* The code below assumes BID. It also needs _MPFR_IEEE_FLOATS
     492       due to the use of union mpfr_ieee_double_extract. */
     493  #if _MPFR_IEEE_FLOATS && defined(DECIMAL_BID_FORMAT)
     494    /* The volatile below avoids _Decimal64 constant propagation, which is
     495       buggy for non-canonical encoding in various GCC versions on the x86 and
     496       x86_64 targets: failure with gcc (Debian 20190719-1) 10.0.0 20190718
     497       (experimental) [trunk revision 273586]; the MPFR test was not failing
     498       with previous GCC versions, but GCC versions 5 to 9 are also affected
     499       on the simple testcase at:
     500       https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91226
     501    */
     502    volatile _Decimal64 d = 9999999999999999.dd;
     503    union mpfr_ieee_double_extract x;
     504    union ieee_double_decimal64 y;
     505  
     506    MPFR_ASSERTN (sizeof (x) == 8);
     507    MPFR_ASSERTN (sizeof (y) == 8);
     508    /* test for non-canonical encoding */
     509    y.d64 = d;
     510    memcpy (&x, &y, 8);
     511    /* if BID, we have sig=0, exp=1735, manh=231154, manl=1874919423 */
     512    if (x.s.sig == 0 && x.s.exp == 1735 && x.s.manh == 231154 &&
     513        x.s.manl == 1874919423)
     514      {
     515        mpfr_t z;
     516        mpfr_init2 (z, 54); /* 54 bits ensure z is exact, since 10^16 < 2^54 */
     517        x.s.manl += 1; /* then the significand equals 10^16 */
     518        memcpy (&y, &x, 8);
     519        mpfr_set_decimal64 (z, y.d64, MPFR_RNDN);
     520        if (MPFR_NOTZERO (z) || MPFR_IS_NEG (z))
     521          {
     522            int i;
     523            printf ("Error in noncanonical on");
     524            for (i = 0; i < 8; i++)
     525              printf (" %02X", ((unsigned char *)&y)[i]);
     526            printf ("\nExpected +0, got:\n");
     527            mpfr_dump (z);
     528            exit (1);
     529          }
     530        mpfr_clear (z);
     531      }
     532    else
     533      printf ("Warning! Unexpected value of x in noncanonical.\n");
     534  #endif
     535  }
     536  
     537  /* generate random sequences of 8 bytes and interpret them as _Decimal64 */
     538  static void
     539  check_random_bytes (void)
     540  {
     541    union {
     542      _Decimal64 d;
     543      unsigned char c[8];
     544    } x;
     545    int i;
     546    mpfr_t y;
     547    _Decimal64 e;
     548  
     549    mpfr_init2 (y, 55); /* 55 = 1 + ceil(16*log(10)/log(2)), thus ensures
     550                           that if a decimal64 number is converted to a 55-bit
     551                           value and back, we should get the same value */
     552    for (i = 0; i < 100000; i++)
     553      {
     554        int j;
     555        for (j = 0; j < 8; j++)
     556          x.c[j] = randlimb () & 255;
     557        mpfr_set_decimal64 (y, x.d, MPFR_RNDN);
     558        e = mpfr_get_decimal64 (y, MPFR_RNDN);
     559        if (!mpfr_nan_p (y))
     560          if (x.d != e)
     561            {
     562              printf ("check_random_bytes failed\n");
     563              printf ("x.d="); print_decimal64 (x.d);
     564              printf ("y="); mpfr_dump (y);
     565              printf ("e  ="); print_decimal64 (e);
     566              exit (1);
     567            }
     568      }
     569    mpfr_clear (y);
     570  }
     571  
     572  int
     573  main (int argc, char *argv[])
     574  {
     575    int verbose = argc > 1;
     576  
     577    tests_start_mpfr ();
     578    mpfr_test_init ();
     579  
     580    if (verbose)
     581      {
     582  #ifdef DECIMAL_DPD_FORMAT
     583        printf ("Using DPD encoding\n");
     584  #endif
     585  #ifdef DECIMAL_BID_FORMAT
     586        printf ("Using BID encoding\n");
     587  #endif
     588      }
     589  
     590  #if !defined(MPFR_ERRDIVZERO)
     591    check_random_bytes ();
     592  #endif
     593    noncanonical ();
     594    check_misc ();
     595    check_random ();
     596    check_native ();
     597  #if !defined(MPFR_ERRDIVZERO)
     598    check_overflow ();
     599  #endif
     600    check_tiny ();
     601    powers_of_10 ();
     602  
     603    tests_end_mpfr ();
     604    return 0;
     605  }
     606  
     607  #else /* MPFR_WANT_DECIMAL_FLOATS */
     608  
     609  int
     610  main (void)
     611  {
     612    return 77;
     613  }
     614  
     615  #endif /* MPFR_WANT_DECIMAL_FLOATS */