[Gmp-commit] /var/hg/gmp: 2 new changesets
mercurial at gmplib.org
mercurial at gmplib.org
Thu Aug 1 19:54:44 UTC 2019
details: /var/hg/gmp/rev/0fe70584021b
changeset: 17783:0fe70584021b
user: Torbjorn Granlund <tg at gmplib.org>
date: Thu Aug 01 15:19:45 2019 +0200
description:
Ignore leading zeros including ones after radix point to avoid invalid output formats.
details: /var/hg/gmp/rev/6ccfae04ecb8
changeset: 17784:6ccfae04ecb8
user: Torbjorn Granlund <tg at gmplib.org>
date: Thu Aug 01 15:21:12 2019 +0200
description:
Add several more fixed test cases.
diffstat:
mpf/set_str.c | 36 ++++++++++++------
tests/mpf/t-conv.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 125 insertions(+), 14 deletions(-)
diffs (226 lines):
diff -r 730118f1173e -r 6ccfae04ecb8 mpf/set_str.c
--- a/mpf/set_str.c Tue Jul 30 22:13:50 2019 +0200
+++ b/mpf/set_str.c Thu Aug 01 15:21:12 2019 +0200
@@ -2,8 +2,8 @@
in base BASE to a float in dest. If BASE is zero, the leading characters
of STRING is used to figure out the base.
-Copyright 1993-1997, 2000-2003, 2005, 2007, 2008, 2011, 2013 Free Software
-Foundation, Inc.
+Copyright 1993-1997, 2000-2003, 2005, 2007, 2008, 2011, 2013, 2019 Free
+Software Foundation, Inc.
This file is part of the GNU MP Library.
@@ -126,12 +126,15 @@
size_t i, j;
int c;
int negative;
- char *dotpos = 0;
+ char *dotpos;
const char *expptr;
int exp_base;
const char *point = GMP_DECIMAL_POINT;
size_t pointlen = strlen (point);
const unsigned char *digit_value;
+ int incr;
+ size_t n_zeros_skipped;
+
TMP_DECL;
c = (unsigned char) *str;
@@ -198,6 +201,10 @@
TMP_MARK;
s = begs = (char *) TMP_ALLOC (str_size + 1);
+ incr = 0;
+ n_zeros_skipped = 0;
+ dotpos = NULL;
+
/* Loop through mantissa, converting it from ASCII to raw byte values. */
for (i = 0; i < str_size; i++)
{
@@ -230,7 +237,13 @@
TMP_FREE;
return -1;
}
- *s++ = dig;
+ *s = dig;
+ incr |= dig != 0;
+ s += incr; /* Increment after first non-0 digit seen. */
+ if (dotpos != NULL)
+ /* Count skipped zeros between radix point and first non-0
+ digit. */
+ n_zeros_skipped += 1 - incr;
}
}
c = (unsigned char) *++str;
@@ -251,19 +264,14 @@
#if 0
size_t n_chars_needed;
- /* This breaks things like 0.000...0001. To safely ignore superfluous
- digits, we need to skip over leading zeros. */
+ /* This needs careful testing. Leave disabled for now. */
/* Just consider the relevant leading digits of the mantissa. */
LIMBS_PER_DIGIT_IN_BASE (n_chars_needed, prec, base);
if (str_size > n_chars_needed)
str_size = n_chars_needed;
#endif
- LIMBS_PER_DIGIT_IN_BASE (ma, str_size, base);
- mp = TMP_ALLOC_LIMBS (ma);
- mn = mpn_set_str (mp, (unsigned char *) begs, str_size, base);
-
- if (mn == 0)
+ if (str_size == 0)
{
SIZ(x) = 0;
EXP(x) = 0;
@@ -271,6 +279,10 @@
return 0;
}
+ LIMBS_PER_DIGIT_IN_BASE (ma, str_size, base);
+ mp = TMP_ALLOC_LIMBS (ma);
+ mn = mpn_set_str (mp, (unsigned char *) begs, str_size, base);
+
madj = 0;
/* Ignore excess limbs in MP,MSIZE. */
if (mn > prec)
@@ -310,7 +322,7 @@
else
exp_in_base = 0;
if (dotpos != 0)
- exp_in_base -= s - dotpos;
+ exp_in_base -= s - dotpos + n_zeros_skipped;
divflag = exp_in_base < 0;
exp_in_base = ABS (exp_in_base);
diff -r 730118f1173e -r 6ccfae04ecb8 tests/mpf/t-conv.c
--- a/tests/mpf/t-conv.c Tue Jul 30 22:13:50 2019 +0200
+++ b/tests/mpf/t-conv.c Thu Aug 01 15:21:12 2019 +0200
@@ -1,6 +1,6 @@
/* Test mpf_get_str and mpf_set_str.
-Copyright 1996, 2000, 2001, 2008 Free Software Foundation, Inc.
+Copyright 1996, 2000, 2001, 2008, 2019 Free Software Foundation, Inc.
This file is part of the GNU MP Library test suite.
@@ -71,8 +71,29 @@
/* First test some specific values. */
+ mpf_set_str (y, "1.23456", 0);
+ mpf_set_str (x, "1.23456", 10);
+ MPF_CHECK_FORMAT (x);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
+ mpf_set_str (x, "00000000000000000000000000000000000000001.23456", 10);
+ MPF_CHECK_FORMAT (x);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
+ mpf_set_str (x, "0.000000000000000000000000000000000000000123456e40", 10);
+ MPF_CHECK_FORMAT (x);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
+ mpf_set_str (x, ".000000000000000000000000000000000000000123456e40", 10);
+ MPF_CHECK_FORMAT (x);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
+ mpf_set_str (x, "00000000000000000000.00000000000000000000123456e21", 10);
+ MPF_CHECK_FORMAT (x);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
+
mpf_set_str (y, "1.23456e1000", 0);
-
mpf_set_str (x, "1.23456e1000", 10);
if (mpf_cmp (x, y) != 0)
abort ();
@@ -82,6 +103,84 @@
mpf_set_str (x, "1.23456e+1000", 10);
if (mpf_cmp (x, y) != 0)
abort ();
+ mpf_set_str (x, "00000000000000000000000000000000000000001.23456e+1000", 10);
+ MPF_CHECK_FORMAT (x);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
+ mpf_set_str (x, "0.000000000000000000000000000000000000000123456e+1040", 10);
+ MPF_CHECK_FORMAT (x);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
+ mpf_set_str (x, ".000000000000000000000000000000000000000123456e+1040", 10);
+ MPF_CHECK_FORMAT (x);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
+ mpf_set_str (x, "00000000000000000000.00000000000000000000123456e+1021", 10);
+ MPF_CHECK_FORMAT (x);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
+
+ mpf_set_str (y, "1.23456", 16);
+ mpf_set_str (x, "00000000000000000000000000000000000000001.23456", 16);
+ MPF_CHECK_FORMAT (x);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
+ mpf_set_str (x, "0.000000000000000000000000000000000000000123456 at 28", 16);
+ MPF_CHECK_FORMAT (x);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
+ mpf_set_str (x, ".000000000000000000000000000000000000000123456 at 28", 16);
+ MPF_CHECK_FORMAT (x);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
+ mpf_set_str (x, "00000000000000000000.00000000000000000000123456 at 15", 16);
+ MPF_CHECK_FORMAT (x);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
+
+ mpf_set_str (y, "0", 10);
+ mpf_set_str (x, "00000000000000000000000000000000000000000000000000000", 10);
+ MPF_CHECK_FORMAT (x);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
+ mpf_set_str (x, "0000000000000000000000000000000000000000000000000000.", 10);
+ MPF_CHECK_FORMAT (x);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
+ mpf_set_str (x, "000000000000000000000000000000000000000000000000000.0", 10);
+ MPF_CHECK_FORMAT (x);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
+ mpf_set_str (x, ".0000000000000000000000000000000000000000000000000000", 10);
+ MPF_CHECK_FORMAT (x);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
+ mpf_set_str (x, "0.000000000000000000000000000000000000000000000000000", 10);
+ MPF_CHECK_FORMAT (x);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
+
+ mpf_set_str (y, "0", 16);
+ mpf_set_str (x, "00000000000000000000000000000000000000000000000000000", 16);
+ MPF_CHECK_FORMAT (x);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
+ mpf_set_str (x, "0000000000000000000000000000000000000000000000000000.", 16);
+ MPF_CHECK_FORMAT (x);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
+ mpf_set_str (x, "000000000000000000000000000000000000000000000000000.0", 16);
+ MPF_CHECK_FORMAT (x);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
+ mpf_set_str (x, ".0000000000000000000000000000000000000000000000000000", 16);
+ MPF_CHECK_FORMAT (x);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
+ mpf_set_str (x, "0.000000000000000000000000000000000000000000000000000", 16);
+ MPF_CHECK_FORMAT (x);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
/* Now test random values. */
More information about the gmp-commit
mailing list