Correctly parse decimals between 0 and -1.

The negative sign was being lost because stoll("-0") is 0.
Also permits parsing decimals between -1 and 1 without the leading 0.
This commit is contained in:
Craig 2019-08-24 05:45:31 +02:00 committed by John Ralls
parent e8543008c0
commit 04aab7cea3
2 changed files with 12 additions and 3 deletions

View File

@ -120,7 +120,7 @@ using boost::smatch;
using boost::regex_search;
GncNumeric::GncNumeric(const std::string& str, bool autoround)
{
static const std::string numer_frag("(-?[0-9]+)");
static const std::string numer_frag("(-?[0-9]*)");
static const std::string denom_frag("([0-9]+)");
static const std::string hex_frag("(0x[a-f0-9]+)");
static const std::string slash( "[ \\t]*/[ \\t]*");
@ -175,10 +175,13 @@ GncNumeric::GncNumeric(const std::string& str, bool autoround)
}
if (regex_search(str, m, decimal))
{
GncInt128 high(stoll(m[1].str()));
auto neg = (m[1].length() && m[1].str()[0] == '-');
GncInt128 high((neg && m[1].length() > 1) || (!neg && m[1].length()) ?
stoll(m[1].str()) : 0);
GncInt128 low(stoll(m[2].str()));
int64_t d = powten(m[2].str().length());
GncInt128 n = high * d + (high >= 0 ? low : -low);
GncInt128 n = high * d + (neg ? -low : low);
if (!autoround && n.isBig())
{
std::ostringstream errmsg;

View File

@ -179,6 +179,12 @@ TEST(gncnumeric_constructors, test_string_constructor)
std::out_of_range);
EXPECT_THROW(GncNumeric bad_string("Four score and seven"),
std::invalid_argument);
GncNumeric neg_decimal_frac("-0.12345");
EXPECT_EQ(-12345, neg_decimal_frac.num());
EXPECT_EQ(100000, neg_decimal_frac.denom());
GncNumeric neg_decimal_frac_nozero("-.12345");
EXPECT_EQ(-12345, neg_decimal_frac_nozero.num());
EXPECT_EQ(100000, neg_decimal_frac_nozero.denom());
}
TEST(gncnumeric_output, string_output)