add amount division API and test case
This commit is contained in:
parent
326f3b2a43
commit
0214e426a6
@ -251,6 +251,20 @@ TALER_amount_add (struct TALER_Amount *sum,
|
|||||||
const struct TALER_Amount *a2);
|
const struct TALER_Amount *a2);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divide an amount by a float. Note that this function
|
||||||
|
* may introduce a rounding error!
|
||||||
|
*
|
||||||
|
* @param result where to store @a dividend / @a divisor
|
||||||
|
* @param dividend amount to divide
|
||||||
|
* @param divisor by what to divide, must be positive
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TALER_amount_divide (struct TALER_Amount *result,
|
||||||
|
const struct TALER_Amount *dividend,
|
||||||
|
uint32_t divisor);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normalize the given amount.
|
* Normalize the given amount.
|
||||||
*
|
*
|
||||||
|
@ -1005,6 +1005,21 @@ enum TALER_ErrorCode
|
|||||||
*/
|
*/
|
||||||
TALER_EC_PAY_FAILED_COMPUTE_PROPOSAL_HASH = 2123,
|
TALER_EC_PAY_FAILED_COMPUTE_PROPOSAL_HASH = 2123,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Failed to locate merchant's account information matching the
|
||||||
|
* wire hash given in the proposal.
|
||||||
|
* This response is
|
||||||
|
* provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
|
||||||
|
*/
|
||||||
|
TALER_EC_PAY_WIRE_HASH_UNKNOWN = 2124,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We got different currencies for the wire fee and the maximum wire
|
||||||
|
* fee. This response is provided with HTTP status code
|
||||||
|
* MHD_HTTP_INTERNAL_SERVER_ERROR.
|
||||||
|
*/
|
||||||
|
TALER_EC_PAY_WIRE_FEE_CURRENCY_MISSMATCH = 2125,
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Integer overflow with sepcified timestamp argument detected.
|
* Integer overflow with sepcified timestamp argument detected.
|
||||||
|
@ -565,4 +565,32 @@ TALER_amount_to_string (const struct TALER_Amount *amount)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divide an amount by a float. Note that this function
|
||||||
|
* may introduce a rounding error!
|
||||||
|
*
|
||||||
|
* @param result where to store @a dividend / @a divisor
|
||||||
|
* @param dividend amount to divide
|
||||||
|
* @param divisor by what to divide, must be positive
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TALER_amount_divide (struct TALER_Amount *result,
|
||||||
|
const struct TALER_Amount *dividend,
|
||||||
|
uint32_t divisor)
|
||||||
|
{
|
||||||
|
uint64_t modr;
|
||||||
|
|
||||||
|
GNUNET_assert (0 != divisor);
|
||||||
|
*result = *dividend;
|
||||||
|
if (1 == divisor)
|
||||||
|
return;
|
||||||
|
modr = result->value % divisor;
|
||||||
|
result->value /= divisor;
|
||||||
|
/* modr is a 32-bit value, so we can safely multiply by (<32-bit) base and add fraction! */
|
||||||
|
modr = (modr * TALER_AMOUNT_FRAC_BASE) + result->fraction;
|
||||||
|
GNUNET_assert (modr < TALER_AMOUNT_FRAC_BASE * divisor);
|
||||||
|
result->fraction = (uint32_t) (modr / divisor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* end of amount.c */
|
/* end of amount.c */
|
||||||
|
@ -197,6 +197,43 @@ main(int argc,
|
|||||||
TALER_amount_subtract (&a3, &a1, &a2));
|
TALER_amount_subtract (&a3, &a1, &a2));
|
||||||
GNUNET_assert (UINT64_MAX - 1 == a3.value);
|
GNUNET_assert (UINT64_MAX - 1 == a3.value);
|
||||||
GNUNET_assert (TALER_AMOUNT_FRAC_BASE - 1 == a3.fraction);
|
GNUNET_assert (TALER_AMOUNT_FRAC_BASE - 1 == a3.fraction);
|
||||||
|
|
||||||
|
/* test division */
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_string_to_amount ("EUR:3.33",
|
||||||
|
&a1));
|
||||||
|
TALER_amount_divide (&a2,
|
||||||
|
&a1,
|
||||||
|
1);
|
||||||
|
GNUNET_assert (0 == strcasecmp ("EUR",
|
||||||
|
a2.currency));
|
||||||
|
GNUNET_assert (3 == a2.value);
|
||||||
|
GNUNET_assert (TALER_AMOUNT_FRAC_BASE / 100 * 33 == a2.fraction);
|
||||||
|
|
||||||
|
TALER_amount_divide (&a2,
|
||||||
|
&a1,
|
||||||
|
3);
|
||||||
|
GNUNET_assert (0 == strcasecmp ("EUR",
|
||||||
|
a2.currency));
|
||||||
|
GNUNET_assert (1 == a2.value);
|
||||||
|
GNUNET_assert (TALER_AMOUNT_FRAC_BASE / 100 * 11 == a2.fraction);
|
||||||
|
|
||||||
|
TALER_amount_divide (&a2,
|
||||||
|
&a1,
|
||||||
|
2);
|
||||||
|
GNUNET_assert (0 == strcasecmp ("EUR",
|
||||||
|
a2.currency));
|
||||||
|
GNUNET_assert (1 == a2.value);
|
||||||
|
GNUNET_assert (TALER_AMOUNT_FRAC_BASE / 1000 * 665 == a2.fraction);
|
||||||
|
TALER_amount_divide (&a2,
|
||||||
|
&a1,
|
||||||
|
TALER_AMOUNT_FRAC_BASE * 2);
|
||||||
|
GNUNET_assert (0 == strcasecmp ("EUR",
|
||||||
|
a2.currency));
|
||||||
|
GNUNET_assert (0 == a2.value);
|
||||||
|
GNUNET_assert (1 == a2.fraction);
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user