3
$\begingroup$

My problem is due to the fact that I am manipulating a set of amounts that span over some intervals of time (start date/end date) and that are rounded to cents. I have to multiply each of them by some fraction (percentage), and I have to round the results to cents. Then I have to match the sum of what I calculated to the total amount (the sum of all chunks) multiplied by the same fraction (to make sure that precision loss didn't cause a lot of damage to the "big picture"), and if I have an error, I put it into the last (or first?) calculated value. Then I have to "balance" all the amounts for every start date I have (and, probably, for an end date too).

Example: $A_i$ is a monetary amount that is associated to a date $D_i$, $i\in [1, n]\subset\mathbb{N}$. I need to calculate commissions for every amount. I know the commission rate $cr$. Every commission amount should be rounded. So, I have $n$ commission amounts $CA_i$. The problem is that after rounding off the amounts, I get that ($\lceil x\rceil$ is the rounded value of $x$ in what follows): $$\sum_{i=1}^n \lceil A_i*cr\rceil \neq \left\lceil\biggl(\sum_{i=1}^n A_i\biggr)*cr\right\rceil$$

Let's assume that I correct this error by adding the difference to $AC_n$. Now, I might have another problem: let $\{d_j\}_{1\leq j\leq m}$ be the set of all (distinct) dates $D_i$. So, I have that $$\sum_{k=1}^? \lceil B_k cr\rceil \neq \left\lceil\biggl(\sum_{k=1}^? B_k\biggr)*cr\right\rceil$$ where $B_k = \{A_i \text{ such that } D_i = d\}$, for some date $d\in \{d_k\}$. In other words, if I group the rounded results by date, there will still be an error compared to the total commission for this date. So, I should balance across every date (not forgetting about the total amount!)

This balancing is a very intuition-based approach, which might work or not. I've been looking for some formalization on the internet, but All I got was either the classic numerical analysis (after some brief introduction to floating point representation errors and rounding errors, it immediately goes to linear equations etc.) or just "Don't use floating point to represent money" articles. Are there any accessible sources on the specific topic of monetary calculations?

$\endgroup$
  • 1
    $\begingroup$ It's unclear what you are asking: what are you trying to accomplish exactly? $\endgroup$ – cody Sep 14 '15 at 14:16
  • $\begingroup$ I've added a kind of example, but you're right, it is hard for me to explain the problem clearly. The example is somewhat specific to my program. $\endgroup$ – Igor Sep 14 '15 at 14:34
  • $\begingroup$ So is the question: "how do I get the smallest amount of rounding error for this formula"? $\endgroup$ – cody Sep 14 '15 at 14:43
  • $\begingroup$ Not really, it is more like "how do I adjust the rounding error so that it seems that I don't have one". The paragon of the commission amount being $\lceil (\sum_i A_i)*cr\rceil$ (it's the amount I compare all others to). $\endgroup$ – Igor Sep 14 '15 at 14:45
5
$\begingroup$

Let me illustrate one problem which could happen, and one way to solve it. You want to distribute a given amount of cents $N$ into $k$ piles, in proportions $p_1,\ldots,p_k$, where $p_1,\ldots,p_k \geq 0$ and $p_1 + \cdots + p_k = 1$. The problem is that $Np_i$ need not be an integer. As a simple example, you might want to divide $20$ cents into $1/3:2/3$ proportions. The fractional solution is $$ 6\frac{2}{3}:13\frac{1}{3}. $$ It seems fair to round this to $7:13$ since $2/3 > 1/3$. More generally, compute $m_i = \lfloor N p_i \rfloor$ and $r_i = Np_i - m_i$. Here $m_i$ is the initial allocation and $r_i$ is the fractional one that you want to round. You need to add up some amount $R = N - \sum_i m_i$ of cents to make the total exactly $N$. Sort the $r_i$ in non-increasing order, and give one cent to the first $R$ parts according to this order (break ties arbitrarily). This is just a generalization of the example above.

$\endgroup$
  • $\begingroup$ Thanks, Yuval. This is exactly my problem, a little simplified (one-dimentional, one can say). Now, is there a theory on this subject? Maybe with some common examples from the financial domain? $\endgroup$ – Igor Sep 14 '15 at 14:42
  • $\begingroup$ There might be, but I don't know what the keywords are. $\endgroup$ – Yuval Filmus Sep 14 '15 at 14:45
1
$\begingroup$

Error analysis of floating point programs is a complex fields that far extends the scope of financial calculations. In general it is a quite complex field, which takes a bit of experience to get comfortable with.

Some starter papers:

The reason that textbooks and online sources recommend fixed-precision arithmetic for financial computation is because this is the textbook example of the utility of fixed-point numbers!

The main reason for floats is the case where it is unclear what the "correct" scale for the computation is (in meterology, for example, or other fields of physical calculation). In finance, you literally have a fixed smallest possible quantity: the cent. Coupled with the fact that the largest probable sum that you will ever have to manipulate (say, on the order of 100 trillion dollars), this means that every operation can be perfectly represented at maximum precision.

This is the ideal use case for representing everything as either a fixed point number, or simply a large enough integer representing the number of cents. It's not hard to implement the correct percentage operations that round to the nearest cent using integer division, and I suspect that there are many libraries that implement exactly this.

In conclusion: floats are hard, and fixed-precision is the right tool to use for dealing with dollar amounts!

$\endgroup$
  • $\begingroup$ Hi cody, thanks for the answer, but it is not exactly what I was looking for: I am using BigDecimal in my calculations. Even though I do, I still have a problem: if I have a value $101.55 and I have a commission rate at 1%, then I have to multiply 101.55 by 0.01 and I get 1.0155 which is perfectly representable with fixed point. But then I have to round it up to 1.02 (user requirement) and I loose precision. Now, if I have a hundred values like this, I get a possibility of a huge loss. That's where I lack expertise and documentation :( $\endgroup$ – Igor Sep 14 '15 at 14:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.