summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/get_d64.c9
-rw-r--r--tests/tget_set_d64.c27
2 files changed, 36 insertions, 0 deletions
diff --git a/src/get_d64.c b/src/get_d64.c
index 03dbfd916..d5fd4d64c 100644
--- a/src/get_d64.c
+++ b/src/get_d64.c
@@ -347,6 +347,15 @@ mpfr_get_decimal64 (mpfr_srcptr src, mpfr_rnd_t rnd_mode)
which corresponds to s=[0.]1000...000 and e=-397 */
if (e < -397)
{
+ if (rnd_mode == MPFR_RNDN && e == -398)
+ {
+ /* If 0.5E-398 < |src| < 1E-398 (smallest subnormal),
+ src should round to +/- 1E-398 in MPFR_RNDN. */
+ mpfr_get_str (s, &e, 10, 1, src, MPFR_RNDA);
+ return e == -398 && s[negative] <= '5' ?
+ get_decimal64_zero (negative) :
+ get_decimal64_min (negative);
+ }
if (rnd_mode == MPFR_RNDZ || rnd_mode == MPFR_RNDN
|| (rnd_mode == MPFR_RNDD && negative == 0)
|| (rnd_mode == MPFR_RNDU && negative != 0))
diff --git a/tests/tget_set_d64.c b/tests/tget_set_d64.c
index 444307756..de35fba4e 100644
--- a/tests/tget_set_d64.c
+++ b/tests/tget_set_d64.c
@@ -289,6 +289,32 @@ check_overflow (void)
exit (1);
}
+static void
+check_tiny (void)
+{
+ mpfr_t x;
+ _Decimal64 d;
+
+ /* If 0.5E-398 < |x| < 1E-398 (smallest subnormal), x should round
+ to +/- 1E-398 in MPFR_RNDN. Note: the midpoint 0.5E-398 between
+ 0 and 1E-398 is not a representable binary number, so that there
+ are no tests for it. */
+ mpfr_init2 (x, 128);
+ mpfr_set_str (x, "1E-398", 10, MPFR_RNDZ);
+ d = mpfr_get_decimal64 (x, MPFR_RNDN);
+ MPFR_ASSERTN (d == 1.0E-398dd);
+ mpfr_neg (x, x, MPFR_RNDN);
+ d = mpfr_get_decimal64 (x, MPFR_RNDN);
+ MPFR_ASSERTN (d == -1.0E-398dd);
+ mpfr_set_str (x, "0.5E-398", 10, MPFR_RNDU);
+ d = mpfr_get_decimal64 (x, MPFR_RNDN);
+ MPFR_ASSERTN (d == 1.0E-398dd);
+ mpfr_neg (x, x, MPFR_RNDN);
+ d = mpfr_get_decimal64 (x, MPFR_RNDN);
+ MPFR_ASSERTN (d == -1.0E-398dd);
+ mpfr_clear (x);
+}
+
int
main (void)
{
@@ -306,6 +332,7 @@ main (void)
check_random ();
check_native ();
check_overflow ();
+ check_tiny ();
tests_end_mpfr ();
return 0;