Skip to content

Commit

Permalink
Reimplement gnc_numeric in terms of GncNumeric instead of GncRational.
Browse files Browse the repository at this point in the history
Except when how has DenomType::exact; that triggers direct use of GncRational
and direct rounding to the specified denominator.
  • Loading branch information
jralls committed Feb 20, 2017
1 parent c3d22c4 commit ff7e6a3
Show file tree
Hide file tree
Showing 8 changed files with 255 additions and 356 deletions.
3 changes: 2 additions & 1 deletion src/app-utils/gnc-ui-util.c
Expand Up @@ -1378,7 +1378,8 @@ PrintAmountInternal(char *buf, gnc_numeric val, const GNCPrintAmountInfo *info)
{
rounding.num = 5; /* Limit the denom to 10^13 ~= 2^44, leaving max at ~524288 */
rounding.denom = pow(10, max_dp + 1);
val = gnc_numeric_add(val, rounding, val.denom, GNC_HOW_RND_TRUNC);
val = gnc_numeric_add(val, rounding, val.denom,
GNC_HOW_DENOM_EXACT | GNC_HOW_RND_TRUNC);

if (gnc_numeric_check(val))
{
Expand Down
34 changes: 20 additions & 14 deletions src/app-utils/test/test-print-parse-amount.cpp
Expand Up @@ -39,22 +39,12 @@ test_num_print_info (gnc_numeric n, GNCPrintAmountInfo print_info, int line)
const char *s;
gboolean ok, print_ok;

auto msg = "[PrintAmountInternal()] Bad numeric from rounding: GNC_ERROR_OVERFLOW.";
auto log_domain = "gnc.gui";
auto loglevel = static_cast<GLogLevelFlags>(G_LOG_LEVEL_WARNING);
auto check = test_error_struct_new (log_domain, loglevel, msg);

/* Throws overflows during rounding step in xaccPrintAmount when the "fraction" is high. See bug 665707. */
auto hdlr = g_log_set_handler (log_domain, loglevel,
(GLogFunc)test_checked_handler, &check);
s = xaccPrintAmount (n, print_info);
print_ok = (s && s[0] != '\0');
if (!print_ok)
return;

ok = xaccParseAmount (s, print_info.monetary, &n_parsed, NULL);
g_log_remove_handler (log_domain, hdlr);


do_test_args (ok, "parsing failure", __FILE__, __LINE__,
"num: %s, string %s (line %d)", gnc_numeric_to_string (n), s, line);
Expand All @@ -64,8 +54,6 @@ test_num_print_info (gnc_numeric n, GNCPrintAmountInfo print_info, int line)
"start: %s, string %s, finish: %s (line %d)",
gnc_numeric_to_string (n), s,
gnc_numeric_to_string (n_parsed), line);
test_error_struct_free (check);

}

static void
Expand All @@ -90,7 +78,8 @@ test_num (gnc_numeric n)
print_info.force_fit = 0;
print_info.round = 0;

n1 = gnc_numeric_convert (n, fraction, GNC_HOW_RND_ROUND_HALF_UP);
n1 = gnc_numeric_convert (n, fraction, GNC_HOW_DENOM_EXACT |
GNC_HOW_RND_ROUND_HALF_UP);
if (gnc_numeric_check(n1))
{
do_test_args((gnc_numeric_check(n1) == GNC_ERROR_OVERFLOW),
Expand Down Expand Up @@ -133,6 +122,20 @@ static void
run_tests (void)
{
int i;
auto msg1 = "[gnc_numeric_mul()] Cannot be represented as a GncNumeric. Its integer value is too large.\n";
auto msg2 = "[gnc_numeric_mul()] Overflow during rounding.";
auto msg3 = "[convert()] Value too large to represent as int64_t";
const char* log_domain = "qof";
auto loglevel = static_cast<GLogLevelFlags>(G_LOG_LEVEL_WARNING);
auto check1 = test_error_struct_new (log_domain, loglevel, msg1);
auto check2 = test_error_struct_new (log_domain, loglevel, msg2);
auto check3 = test_error_struct_new (log_domain, loglevel, msg3);
test_add_error(check1);
test_add_error(check2);
test_add_error(check3);
/* Throws overflows during rounding step in xaccPrintAmount when the "fraction" is high. See bug 665707. */
auto hdlr = g_log_set_handler (log_domain, loglevel,
(GLogFunc)test_list_handler, nullptr);

for (i = 0; i < 50; i++)
{
Expand All @@ -147,10 +150,13 @@ run_tests (void)
IS_VALID_NUM(n1, n);
test_num (n);

n1 = gnc_numeric_mul (n, n, n.denom, GNC_HOW_RND_ROUND_HALF_UP);
n1 = gnc_numeric_mul (n, n, n.denom,
GNC_HOW_DENOM_EXACT | GNC_HOW_RND_ROUND_HALF_UP);
IS_VALID_NUM(n1, n);
test_num (n);
}
g_log_remove_handler (log_domain, hdlr);
test_clear_error_list();
}

int
Expand Down

0 comments on commit ff7e6a3

Please sign in to comment.