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