diff options
| author | Florian Dold <florian.dold@gmail.com> | 2020-01-17 18:59:15 +0100 | 
|---|---|---|
| committer | Florian Dold <florian.dold@gmail.com> | 2020-01-17 18:59:15 +0100 | 
| commit | 7378b5a081a0d839c3bd63f6ddd359bca50be695 (patch) | |
| tree | ce62b33d65e6372ea59ae7409b193824735ac538 /src/util | |
| parent | ac2e40d0491c0f118ff26cb316ec47e0786818e7 (diff) | |
amount rounding a la Christian
Diffstat (limited to 'src/util')
| -rw-r--r-- | src/util/amount.c | 16 | ||||
| -rw-r--r-- | src/util/test_amount.c | 15 | 
2 files changed, 22 insertions, 9 deletions
| diff --git a/src/util/amount.c b/src/util/amount.c index 48f5d989..1f00b1d6 100644 --- a/src/util/amount.c +++ b/src/util/amount.c @@ -674,23 +674,27 @@ TALER_amount_divide (struct TALER_Amount *result,  /**   * Round the amount to something that can be transferred on the wire. + * The rounding mode is specified via the smallest transferable unit, + * which must only have a fractional part.   *   * @param[in,out] amount amount to round down - * @param max_fractional_digits number of fractional digits to round down to + * @param[in] round_unit unit that should be rounded down to, + *            the value part of this amount must be zero   * @return #GNUNET_OK on success, #GNUNET_NO if rounding was unnecessary,   *         #GNUNET_SYSERR if the amount or currency was invalid   */  int  TALER_amount_round_down (struct TALER_Amount *amount, -                         uint8_t max_fractional_digits) +                         const struct TALER_Amount *round_unit)  {    uint32_t delta; -  uint32_t divisor = 1; -  for (unsigned int i = 0; i < max_fractional_digits; i++) -    divisor *= 10; +  GNUNET_break (0 == round_unit->value); -  delta = amount->fraction % (TALER_AMOUNT_FRAC_BASE / divisor); +  if (0 == round_unit->fraction) +    return GNUNET_OK; + +  delta = amount->fraction % round_unit->fraction;    if (0 == delta)      return GNUNET_NO;    amount->fraction -= delta; diff --git a/src/util/test_amount.c b/src/util/test_amount.c index 4eeccd7e..3bf8e6fb 100644 --- a/src/util/test_amount.c +++ b/src/util/test_amount.c @@ -31,6 +31,7 @@ main (int argc,    struct TALER_Amount a1;    struct TALER_Amount a2;    struct TALER_Amount a3; +  struct TALER_Amount r;    char *c;    GNUNET_log_setup ("test-amout", @@ -237,25 +238,33 @@ main (int argc,    /* test rounding #1 */    GNUNET_assert (GNUNET_OK == +                 TALER_string_to_amount ("EUR:0.01", +                                         &r)); + +  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 (GNUNET_OK == TALER_amount_round_down (&a1, &r)); +  GNUNET_assert (GNUNET_NO == TALER_amount_round_down (&a1, &r));    GNUNET_assert (0 == TALER_amount_cmp (&a1, &a2));    /* test rounding #2 */    GNUNET_assert (GNUNET_OK == +                 TALER_string_to_amount ("EUR:0.001", +                                         &r)); + +  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 (GNUNET_NO == TALER_amount_round_down (&a1, &r));    GNUNET_assert (0 == TALER_amount_cmp (&a1, &a2));    return 0; | 
