[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