From da5b3ba8aeb9d47e4f99cd22847c9b539ff8ee2b Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Wed, 15 Jan 2020 15:17:02 +0100 Subject: round amounts based on config, do unit test for rounding --- src/util/amount.c | 13 +++++++++---- src/util/test_amount.c | 23 +++++++++++++++++++++++ 2 files changed, 32 insertions(+), 4 deletions(-) (limited to 'src/util') diff --git a/src/util/amount.c b/src/util/amount.c index edb9dc060..48f5d9891 100644 --- a/src/util/amount.c +++ b/src/util/amount.c @@ -673,19 +673,24 @@ TALER_amount_divide (struct TALER_Amount *result, /** - * Round the amount to something that can be - * transferred on the wire. + * Round the amount to something that can be transferred on the wire. * * @param[in,out] amount amount to round down + * @param max_fractional_digits number of fractional digits to round down to * @return #GNUNET_OK on success, #GNUNET_NO if rounding was unnecessary, * #GNUNET_SYSERR if the amount or currency was invalid */ int -TALER_amount_round (struct TALER_Amount *amount) +TALER_amount_round_down (struct TALER_Amount *amount, + uint8_t max_fractional_digits) { uint32_t delta; + uint32_t divisor = 1; - delta = amount->fraction % (TALER_AMOUNT_FRAC_BASE / 100); + for (unsigned int i = 0; i < max_fractional_digits; i++) + divisor *= 10; + + delta = amount->fraction % (TALER_AMOUNT_FRAC_BASE / divisor); if (0 == delta) return GNUNET_NO; amount->fraction -= delta; diff --git a/src/util/test_amount.c b/src/util/test_amount.c index d9110eaf8..4eeccd7e0 100644 --- a/src/util/test_amount.c +++ b/src/util/test_amount.c @@ -234,6 +234,29 @@ main (int argc, GNUNET_assert (0 == a2.value); GNUNET_assert (1 == a2.fraction); + /* test rounding #1 */ + + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount ("EUR:4.001", + &a1)); + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount ("EUR:4", + &a2)); + + GNUNET_assert (GNUNET_OK == TALER_amount_round_down (&a1, 2)); + GNUNET_assert (GNUNET_NO == TALER_amount_round_down (&a1, 2)); + GNUNET_assert (0 == TALER_amount_cmp (&a1, &a2)); + + /* test rounding #2 */ + + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount ("EUR:4.001", + &a1)); + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount ("EUR:4.001", + &a2)); + GNUNET_assert (GNUNET_NO == TALER_amount_round_down (&a1, 3)); + GNUNET_assert (0 == TALER_amount_cmp (&a1, &a2)); return 0; } -- cgit v1.2.3