mirror of
https://github.com/Gnucash/gnucash.git
synced 2024-11-22 08:57:17 -06:00
Make the GncNumeric string constructtor work for long decimal numbers.
It was failing to produce a correct representation for input with more than 14 digits after the decimal poin. Fixes Bug 798916. The bug was in powten so this fix may corect other problems too. For example conversion of GncNumeric back to a string also failed in certain circumsances.
This commit is contained in:
parent
d61b962954
commit
71afa3e0fc
@ -48,9 +48,9 @@ static const int64_t pten[] = { 1, 10, 100, 1000, 10000, 100000, 1000000,
|
||||
INT64_C(10000000000), INT64_C(100000000000),
|
||||
INT64_C(1000000000000), INT64_C(10000000000000),
|
||||
INT64_C(100000000000000),
|
||||
INT64_C(1000000000000000),
|
||||
INT64_C(10000000000000000),
|
||||
INT64_C(100000000000000000),
|
||||
INT64_C(1000000000000000000)};
|
||||
INT64_C(100000000000000000)};
|
||||
#define POWTEN_OVERFLOW -5
|
||||
|
||||
int64_t
|
||||
@ -175,9 +175,18 @@ GncNumeric::GncNumeric(const std::string& str, bool autoround)
|
||||
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());
|
||||
auto exp10 = m[2].str().length();
|
||||
int64_t d = powten(exp10);
|
||||
GncInt128 n = high * d + (neg ? -low : low);
|
||||
|
||||
while (exp10 > max_leg_digits)
|
||||
{
|
||||
/* If the arg to powten is bigger than max_leg_digits
|
||||
it returns 10**max_leg_digits so reduce exp10 by
|
||||
that amount */
|
||||
n = n / powten(exp10 - max_leg_digits);
|
||||
exp10 -= max_leg_digits;
|
||||
}
|
||||
|
||||
if (!autoround && n.isBig())
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
|
@ -185,6 +185,12 @@ TEST(gncnumeric_constructors, test_string_constructor)
|
||||
GncNumeric neg_decimal_frac_nozero("-.12345");
|
||||
EXPECT_EQ(-12345, neg_decimal_frac_nozero.num());
|
||||
EXPECT_EQ(100000, neg_decimal_frac_nozero.denom());
|
||||
GncNumeric big_denom(".12345678901234567");
|
||||
EXPECT_EQ(12345678901234567, big_denom.num());
|
||||
EXPECT_EQ(100000000000000000, big_denom.denom());
|
||||
GncNumeric too_big_denom(".123456789012345678");
|
||||
EXPECT_EQ(12345678901234567, too_big_denom.num());
|
||||
EXPECT_EQ(100000000000000000, too_big_denom.denom());
|
||||
}
|
||||
|
||||
TEST(gncnumeric_output, string_output)
|
||||
|
@ -545,8 +545,8 @@ check_add_subtract (void)
|
||||
static const gint64 pten[] = { 1, 10, 100, 1000, 10000, 100000, 1000000,
|
||||
10000000, 100000000, 1000000000, 10000000000,
|
||||
100000000000, 1000000000000, 10000000000000,
|
||||
100000000000000, 10000000000000000,
|
||||
100000000000000000, 1000000000000000000};
|
||||
100000000000000, 1000000000000000,
|
||||
10000000000000000, 100000000000000000};
|
||||
#define POWTEN_OVERFLOW -5
|
||||
|
||||
static inline gint64
|
||||
|
Loading…
Reference in New Issue
Block a user