Using mpq_t for aggregating currencies with wildly varying ranges

Donovan Hide donovanhide at gmail.com
Tue Apr 15 15:28:32 UTC 2014


Hi,

I've been doing some work on making the Ripple Currency format aggregatable
in MySQL by writing a parser and summation functions for this currency
format:

https://ripple.com/wiki/Currency_Format

The docs aren't great! The issue I've got is that I have an mpq_t variable
to which I'm adding various transaction amounts which have hugely variable
exponents, which works well and gives exact results. All denominators are
always powers of ten. However when it comes to outputting the value as a
decimal string, I've been doing something like:

mpq_class total=make_rational(bigendian_decode(args->args[0]));
*length=gmp_sprintf(result,"%.Ff",mpf_class(total,100).get_mpf_t());

which suffers from floating point drift and isn't accurate. I've been
looking at how pgmp for postgres solve the same problem and it's a bit
messy, using integers rather than rationals:

https://github.com/dvarrazzo/pgmp/blob/7ed7844737c5e9c9b1ad72c255ef5a94670ec55c/src/pmpq_io.c#L329-L412

Does anyone have any suggestions on how to format rationals as exact
decimals, with the proviso that the denominator is always a power of ten
and thus the number should be non-recurring?

Cheers,
Donovan.


More information about the gmp-discuss mailing list