I'm looking for a fixed-point standard to use for financial data, do you know any that is worth trying? Do you have any experience on the performance of that hand-made fixed-point classes?
-
2odd that an off-topic question is allowed when there is a bounty. – AndersK Jan 10 '14 at 11:42
-
Have a look at Martin Fowler's [Money pattern](http://martinfowler.com/eaaCatalog/money.html)! – πάντα ῥεῖ Jan 13 '14 at 21:11
-
@claptrap Explain `off-topic` here in particular (can't see any close votes). I know what you mean, but the OP seems to be looking for standard solutions, while there aren't any (AFAIR). May be some c++11 idioms might help ... – πάντα ῥεῖ Jan 13 '14 at 21:14
-
@AugustoRadtke IMHO your problem might be more to have balanced money math, than simply using fixed point decimals without any transaction context. – πάντα ῥεῖ Jan 13 '14 at 21:19
-
@πάνταῥεῖ off-topic in the sense of looking for a tool/library but when a bounty is setup you cannot vote to close it - that is why there are no close votes. nevermind, whatever flyes your boat. – AndersK Jan 14 '14 at 00:48
-
Have you tried doing all your mathematics in integers and simply dividing by 100 at the very last stage? (that can even be avoided by using formatted strings) – GMasucci Jan 14 '14 at 13:04
-
@GMasucci it seems for my case this would be the best solution. but I need to implement "devide" "multiply" etc. – Oleg Vazhnev Jan 16 '14 at 13:20
-
you can do all the above straightforwardly, I will create some code tonight and post it for you with the basics implemented that way you can track the process/theory and expand it as you need:) – GMasucci Jan 16 '14 at 15:24
-
hi again, apologies I have not had time to get to my PC to code this, however there are a few libraries which may help you out: for example http://www.trenki.net/content/view/17/1/ is a quite well featured library and a great place to start. I will get on the code this week. I take it speed is a factor? Also what maximal(+/-) values would you be likely to handle? – GMasucci Jan 21 '14 at 09:29
-
@GMasucci: There's a lot of room for error there, with multiplication, division, input, output, and conversions. Better to wrap it in a class. Like... a small fixed point library. – Mooing Duck Mar 14 '14 at 20:18
7 Answers
Dr.Dobb's has an article about a possible implementation of fixed-point arithmetic type in C++. Check this out.

- 8,101
- 4
- 26
- 35
-
This is the ONLY answer here that has code that can store Dollars as cents. – Mooing Duck Mar 14 '14 at 16:16
Ouch. Financial systems are tricky, your main problem is not fixed point math, the problem are the rounding errors.
You can have a nice spreadsheet full with maverlous calculations with discounts by client type and VAT included. You make a total, you present it to an accountant and he says the values are all wrong. The reason: The output may be formated with only 2 decimal places but internally the value has all the decimal places of a float or double. and they do add up.
You need to know your financials and decide where the base values will be. Meaning what values are the ones the accountants will check (yes it requires business knowledge, hance the 'tricky' part).
The before you save the value to a persistent form (database, file, memory ...) you truncate the extra decimal places that multiplications and divisions may have added.
Quick and dirty solution for N decimal places: ((double)((int)(Value * N * 10.0)))/10.0
Of course you need to check exactly which kind of rounding do your financials require.

- 1,295
- 1
- 12
- 18
-
Your "Quick and dirty solution for N decimal places" should involve 10^N. – Tom Sirgedas Mar 11 '11 at 16:44
-
"your main problem is not fixed point math, the problem are the rounding errors." The problem is rounding errors. The _solution_ is fixed point math – Mooing Duck Mar 14 '14 at 16:05
I use my fixed point math class. It is designed to be more or less a drop in replacement for floats/doubles. http://codef00.com/coding
EDIT: As a side note, I would not personally used a fixed point class for this purpose. I would instead just store the number of cents (or tenths of a cent, or hundredths of a cent as needed). A just do the math directly with that. Then I would scale the value appropriately when displaying to the users.

- 87,561
- 32
- 179
- 238
-
if `class` adds overhead? isn't it better to use macros like here http://eli.thegreenplace.net/files/prog_code/fixnum.cpp.txt ? – Oleg Vazhnev Jan 10 '14 at 09:06
-
5what overhead do you suspect class could add? Why do you think macros could be faster? – Fabio Fracassi Jan 10 '14 at 10:08
-
@EvanTeran: I wrote a fixed point class once too, but abandoned it when someone observed that `a*b/c` is a common operation that both your code and mine adds unnecessary overhead, which is nontrivially fixed. – Mooing Duck Mar 13 '14 at 20:15
-
@Mooing duck: yea the division operator is generally tough to do efficiently :-/. – Evan Teran Mar 14 '14 at 13:36
-
Actually, looking at this code, it doesn't seem to be able to handle non-power-of-2-bases, such as USD in cents. – Mooing Duck Mar 14 '14 at 16:08
-
@MooingDuck: You can split up the bits anyway you like, but fixed point in general (as a concept) has to use approximation for things which are non-power of two. The best way to handle USD is to store the number of cents (or fractions of a cent if needed) and then scale to dollars as needed during display. For example, $1234.56 would be stored as `uint64_t cents = 123456;`. This will avoid all rounding and precision problems. In general, if you are using fixed point for storing money values, you are using the wrong tool for the job. – Evan Teran Mar 14 '14 at 18:21
-
@EvanTeran: Fixed point in general does _NOT_ have to use approximations for things not a power of two. It can be done with any arbitrary base. I've done it, and there is one answer on this page that does it. The class _internally_ has a `uint64_t numerator = 123456;`. The concept of fixed point is storing the numerator of a fraction with a fixed denominator. If the denominator is a power of two, there's many cool bittwiddling tricks that make it faster, but they're not necessary. – Mooing Duck Mar 14 '14 at 18:30
-
1@MooingDuck: That Dr Dobb's solution isn't quite what I had in mind when I said "fixed point", but I see what you mean. In their implementation, the radix point isn't fixed to a bit, but instead to a decimal digit. This is precisly what I suggested they just hid the details in a class. Either way, you will still run into rounding errors, just for different values. For example, how would you represent (1/3) of a dollar? Same problem, just in a different base – Evan Teran Mar 14 '14 at 18:44
-
@EvanTeran: Since (1/3) of a dollar isn't an actual possible value, I don't see the need to be able to store it. It only stores possible values. 33 cents, with 67 cents leftover. – Mooing Duck Mar 14 '14 at 18:45
-
@MooingDuck, so you never plan to use division in your system? Are you simply adding and subtracting values? If so, why bother with a class, why not just use a `uint64_t` directly and say "this is how many cents you have"? (then scaling during display to the user). – Evan Teran Mar 14 '14 at 18:47
-
Also, by using a non-power of two scale factor. You are introducing lots of multiplies for basic operations like assignment. Seems like a n non-ideal solution. (Since the main point of fixed point is that it's faster than `float`s). – Evan Teran Mar 14 '14 at 18:49
-
@EvanTeran: It totally supports division, and will always give a result in cents. Other answers return answers in 128th of a dollar, or worse. Conversions to and from other types does indeed require a multiplication or division. Worse, multiplication requires a division and vice-versa. Yes, this makes it slower, however, it retains _my_ main reason for fixed point: _accuracy and no weird rounding_. For speed, use an internal base that's a power of two, and the optimizer will make it just as fast as these less generic answers. We use a class to get IO, conversion, and multiplication correctly – Mooing Duck Mar 14 '14 at 18:57
-
@MooingDuck: my point is that if you introduce division, you **will** get rounding errors in base 10 as well. Just different rounding errors. The only way to avoid them is to disallow division... It's not just things like (1/3) of a dollar. Something as simple as `$1.25` divided by 2 for two people will result in a lost cent. Like I said, the only way to not have that issue to not allow division. – Evan Teran Mar 14 '14 at 20:01
-
@EvanTeran: The problem isn't that rounding occurs, rounding will _always_ occur, period. So when you do division, and then use subtraction to figure out the remainder. $1.25/2 -> 0.62 and 0.63. That's not fixed point math, that's _any_ type. Except floats, because it doesn't work with floats. Which is _why I use fixed point_. – Mooing Duck Mar 14 '14 at 20:09
-
Also, I didn't introduce division. All of your answers have the division too implicitly, but you've all optimized them out as shifts. Same accuracy loss, because it's the same operation. I'm merely suggesting a more general type that is more accurate for non-powers-of-two such as money. – Mooing Duck Mar 14 '14 at 20:16
-
I think it would be more reasonable have the ability to support fractional cents up to a certain number of digits so the answer would be $0.625 each. But you obviously only allow paying out whole cents. This way, no one gets a free half cent, and no one gets robbed of a half cent. In your system, who gets the bonus half cent? It has to go somewhere because if you just "drop" them, it can add up to a massive discrepancy with actual dollars. (And then you end up with the starting plot of Superman III :-P). – Evan Teran Mar 14 '14 at 20:21
-
As for the division, what I've actually suggested is to **not do it**. If there is no division, there is no need to deal with remainders at all. If your financial system absolutely requires division. I would scale the dollars to something like 1000th of a cent (or more depending on needs) to mitigate the issue as much as possible. – Evan Teran Mar 14 '14 at 20:24
-
@EvanTeran: (A) Your fixed point code can't store 80 cents accurately without dropping fractions of a cent, with _any_ number of bits. Don't bash mine for rounding half cents :P (B) Your fixed point code does have divisions, they're merely disguised behind shifts and bitwise operations. (C) Anything your bitbased code can do, a generic-base fixedpoint class can also do, with _exactly_ the same precision, and I would be surprised if there was any performance difference. The generic version merely offers more options to the user. – Mooing Duck Mar 27 '14 at 19:20
-
@MooingDuck, (A) I know the limitation of my fixed point class, that's why i recommended storing the value in a plain integer in cents (or tenths of a cent). Also, **I did not bash your code at all**, I was simply pointing out that they have similar deficiencies when it comes to division. (B) I know my code has divisions in it... i wrote it. I still wouldn't recommend fixed point for financial calculations at all. The tiny errors introduced will add up to a noticeable amount. – Evan Teran Mar 29 '14 at 17:00
-
@MooingDuck, (C) You seem to be under the impression that I would choose my fixed point class over yours for this purpose. I wouldn't, because I wouldn't use either of them. It's the wrong tool for the job. The ideal solution is to simply use a `int64_t` and say "this is the number of 1000th of a cent you have" (or something to that effect). It's trivial to get right for the general case especially if you can **avoid division** in your code. (division is the one place that no matter what you do, you will end up with rounding and/or truncation). – Evan Teran Mar 29 '14 at 17:01
-
1@EvanTeran: Except for multiplication, input, output, conversions... We have a solution for these sorts of problems in C++. We wrap things in a class. The name for this class is: `fixed_point<100000>` – Mooing Duck Mar 29 '14 at 18:23
IBM's decNumber++

- 28,864
- 15
- 75
- 99
-
2it appears that decNumber++ is all about floating-point, not fixed-point. – Ben Collins Sep 24 '09 at 19:20
ISO specified a decimal extension to C, TR 24732, and to C++, TR 24733. They are available for money on the ISO website. It's not yet part of any published C++ Standard. GCC provides built-in types and a library implementation of it. Another implementation is available from Intel. The most recent push for having this included in C++ is here.

- 4,717
- 2
- 18
- 26
-
gcc "use a radix of ten" so I guess it's designed for `accuracy`, but I need performance, so likely i need "radix of two" implementation. it's seems intel's implementation is "float-point" when I'm looking for fixed-point implementation to have better performance. – Oleg Vazhnev Jan 10 '14 at 12:02
-
These are floating point types, and have the same rounding errors as `float`. These are NOT fixed point. – Mooing Duck Mar 14 '14 at 16:15
A 64-bit int type should suffice for representing all financial values in cents.
You just need to be careful to round percentages correctly, for some definition of correct.

- 70,581
- 9
- 108
- 149
-
See also http://stackoverflow.com/questions/61872/use-float-or-decimal-for-accounting-application-dollar-amount. – lhf Jan 10 '14 at 12:11
-
actually i don't want to just store financical values. I want to do all kind of mathematics. I devide one value to another to compute ratio etc. So I think i need library or something like that. – Oleg Vazhnev Jan 10 '14 at 12:13
-
@lhf: There's more to this than "just" being careful with rounding. Namely, multiplication and division properly are far trickier than simply multiplying and deciding. Also, there's the obvious type holes during conversion and IO. It's best to wrap it in a class. – Mooing Duck Mar 27 '14 at 19:22
Trying to answer directly
Markus Trenkwalder has one that supports some math functions - http://www.trenki.net/content/view/17/1/:
The library consists of various functions for dealing with fixed point numbers (multiplication, division, inversion, sin, cos, sqrt, rsqrt). It also contains a C++ wrapper class which can be used to simplify working with fixed points numbers greatly. I used this fixed point number class in conjunction with my vector_math library to obtain a fixed point vector math library. Doing so made the 3D computations a lot faster compared to the floating point version.
The author made it a point to say his platform does not support floating point though, that's why he did it. Also, note that it's for 3D rendering, the question was for financial data and we want a good library of math functions....
IEEE 754-2008 Decimal Floating-Point Arithmetic specification, aimed at financial applications
This looks like an established way of handling financial data with good support (from Intel and IEEE) - http://software.intel.com/en-us/articles/intel-decimal-floating-point-math-library
To quote:
IEEE 754-2008 Decimal Floating-Point Arithmetic specification, aimed at financial applications, especially in cases where legal requirements make it necessary to use decimal, and not binary floating-point arithmetic (as computation performed with binary floating-point operations may introduce small, but unacceptable errors).
It is NOT fixed-point though, but I thought it is pretty useful for people seeking an answer to this question.
-
Actually, looking at Markus Trenkwalder's code, it doesn't seem to be able to handle non-power-of-2-bases, such as USD in cents. – Mooing Duck Mar 14 '14 at 16:12