mpf_set_str bug

Andrea Bedini andrea.bedini at gmail.com
Sun Nov 9 01:13:36 CET 2008


Hello,

I'm having troubles initializing C++ mpf_class with a string. The very
simple test case is the following:

#include <iostream>
#include <gmpxx.h>

int main (int argc, char *argv[])
{
  mpf_class f("1.2e10");
  std::cout << f << std::endl;
}

It throws invalid_argument at run time. mpf_set_str got called from the
mpf_class constructor with base equals to zero since this is the default
value defined in the mpf_class relevant constructor. But mpf_set_str
behaves differently if base is set to 0 or to 10.

In set_str line 168 reads

  /* Default base to decimal.  */
  if (base == 0)
    base = 10;

but base has been already used at line 140

  exp_base = base;
  if (base < 0)
    {
      exp_base = 10;
      base = -base;
    }

Essentially it ends up with exp_base = 0 and base = 10 instead of
exp_base = 10 and base = 10. My very simple guess is that moving upward
the point where base gets set to its default value solves the
problem. The following patch works for me (and passes all tests).

--8<---------------cut here---------------start------------->8---
--- gmp-4.2.4.orig/mpf/set_str.c        2008-08-25 16:11:37.000000000  
+0200
+++ gmp-4.2.4.new/mpf/set_str.c 2008-11-08 23:33:29.000000000 +0100
@@ -137,6 +137,10 @@
       c = (unsigned char) *++str;
     }

+  /* Default base to decimal.  */
+  if (base == 0)
+    base = 10;
+
   exp_base = base;
   if (base < 0)
     {
@@ -165,10 +169,6 @@
        return -1;
     }

-  /* Default base to decimal.  */
-  if (base == 0)
-    base = 10;
-
   /* Locate exponent part of the input.  Look from the right of the  
string,
      since the exponent is usually a lot shorter than the mantissa.  */
   expptr = NULL;
--8<---------------cut here---------------end--------------->8---

the following test would have caught this bug.

--8<---------------cut here---------------start------------->8---
--- gmp-4.2.4.orig/tests/cxx/t-constr.cc        2007-09-18  
22:00:38.000000000 +0200
+++ gmp-4.2.4.new/tests/cxx/t-constr.cc 2008-11-08 23:45:04.000000000  
+0100
@@ -610,6 +610,11 @@
     int prec = 64, base = 8;
     mpf_class b(a, prec, base); ASSERT_ALWAYS(b == 262143L);
   }
+  {
+    const char *a = "1.234567890e9";
+    int prec = 256;
+    mpf_class b(a, prec); ASSERT_ALWAYS(b == 1234567890L);
+  }

   // mpf_class(const std::string &)
   {
--8<---------------cut here---------------end--------------->8---


That's it.

Thanks,
Andrea

---
Andrea Bedini
andrea.bedini at gmail.com






More information about the gmp-bugs mailing list