Specialising in financial software, over the past 2 decades I have been fighting over this with countless people, teams and companies. For accounting you should only ever use arbitrary precision math library with ability to specify rounding rules. If your programming environment/language does not have one, it is unsuitable to be used for accounting, billing, invoicing, payments, etc. Having the underlying library is,…
I have a personal anecdote on this subject. A long time ago I worked at a bank and I had to calculate a large number of accounts regarding agricultural loans. These were state sponsored loans. When I finished my task (this was a Java job), I found that sometimes the results were off by $0.01. So I asked my boss how I should do the rounding, to which he replied that an error of up to $1 was acceptable. If I recall cor…
64-bit bank balances ‘ought to be enough for anybody’?
101–110 of 372 posts
Re: 64-bit bank balances ‘ought to be enough for anybody’?
#102Earlier quoted context omitted.
Would IEEE decimal128 be sufficient (instead of arbitrary precision)? "Formally introduced in IEEE 754-2008, it is intended for applications where it is necessary to emulate decimal rounding exactly, such as financial and tax computations." https://en.wikipedia.org/wiki/Decimal128_floating-point_form...
Hypothetical solutions that do not exist are none of my concern. Did you know different countries and different currencies have different rounding rules, for example for tax-related calculations? Does "IEEE decimal128" support this? Unless you can get all countries on our planet to agree on a single standard, any solution that does not allow specifying rounding rules is pretty much useless (unless you want to impleme…
Yes, of course IEEE decimal supports setting the rounding mode. The authors of the spec aren't ignorant of what's needed for financial and tax computations.
Use fe_dec_setround from ISO/IEC TR 24732, "Extension for the programming language C to support decimal floating-point arithmetic".
The modes listed at https://www.ibm.com/docs/en/zos/2.5.0?topic=functions-fe-dec... are:
FE_DEC_DOWNWARD
rounds towards minus infinity
FE_DEC_TONEAREST
rounds to nearest
FE_DEC_TOWARDZERO
rounds toward zero
FE_DEC_UPWARD
rounds toward plus infinity
FE_DEC_TONEARESTFROMZERO
rounds to nearest, ties away from zero
_FE_DEC_AWAYFROMZERO
rounds away from zero
_FE_DEC_TONEARESTTOWARDZERO
rounds to nearest, ties toward zero
_FE_DEC_PREPAREFORSHORTER
rounds to prepare for shorter precisionRe: 64-bit bank balances ‘ought to be enough for anybody’?
#103Re: 64-bit bank balances ‘ought to be enough for anybody’?
#104Earlier quoted context omitted.
> Floating point is inherently an approximation - your bank balance should not be an approximation. I think this is a perfect example of bad floating point teaching. Floating point is not an approximation in any sense. If the numerical result of your calculation is representable in floating point you will get an exact answer always. And for results that aren't representable you decide exactly what should be done abou…
In programming, an `int` perfectly represents the integers between INT_MIN and INT_MAX. A `float` on the other hand, approximates the real numbers. It can perfectly represent exactly 0% of them. Having control over the rounding behavior is meaningless - floats cannot correctly represent any non-contrived calculation. Exact representation is important in financial systems.
Like adjusting all your financial calculations to use microcents and partitoning instead of division to keep the result representable by integers? Neither can represent 1/3 even shifted. When you want to do exact calculations with floats, and you can, you just have to set yourself up so that the result is exactly representable, it's not as intractable as you make it seem.
> A `float` on the other hand, approximates the real numbers
Okay so that's not at all what they do, they represent subsets of the reals, just like how integers represent a subset of the reals. Even arbitrary precision libraries can only represent a subset of the rationals.
Re: 64-bit bank balances ‘ought to be enough for anybody’?
#105Earlier quoted context omitted.
BCD is better than IEEE 754 floating point, but simple integers with an implied decimal point is much better than either of those.
BCD makes stored value -> human-readable trivial, at the cost of complicating math on those values. So it's useful for applications where you're mostly doing human input/output stored value. But as soon as you do any non-trivial math on those values, using (fixed point?) integers wins. At the cost of a simple stored value human readable conversion. I'd think most financial applications fall into the category "do math…
Why is a BCD decimal 128 worse at math then a fixed point integer? You are saying it is more CPU efficient? Are you saying some operations with fixed point integer math operations are more accurate then dec128?
I've seen this asserted several times, both in the post and in comments, but I've never seen a single concrete example of it being better. Can someone provide an example?
Re: 64-bit bank balances ‘ought to be enough for anybody’?
#106Specialising in financial software, over the past 2 decades I have been fighting over this with countless people, teams and companies. For accounting you should only ever use arbitrary precision math library with ability to specify rounding rules. If your programming environment/language does not have one, it is unsuitable to be used for accounting, billing, invoicing, payments, etc. Having the underlying library is,…
Would IEEE decimal128 be sufficient (instead of arbitrary precision)? "Formally introduced in IEEE 754-2008, it is intended for applications where it is necessary to emulate decimal rounding exactly, such as financial and tax computations." https://en.wikipedia.org/wiki/Decimal128_floating-point_form...
Re: 64-bit bank balances ‘ought to be enough for anybody’?
#107Earlier quoted context omitted.
Would IEEE decimal128 be sufficient (instead of arbitrary precision)? "Formally introduced in IEEE 754-2008, it is intended for applications where it is necessary to emulate decimal rounding exactly, such as financial and tax computations." https://en.wikipedia.org/wiki/Decimal128_floating-point_form...
Hypothetical solutions that do not exist are none of my concern. Did you know different countries and different currencies have different rounding rules, for example for tax-related calculations? Does "IEEE decimal128" support this? Unless you can get all countries on our planet to agree on a single standard, any solution that does not allow specifying rounding rules is pretty much useless (unless you want to impleme…
IEEE does specify multiple rounding modes. Does it make more sense to use an existing spec, or roll your own numeric library with rounding modes?
Re: 64-bit bank balances ‘ought to be enough for anybody’?
#108Earlier quoted context omitted.
What are the specific challenges to writing financial software? What are common mistakes you see? What are common data structures for representing money (both the common incorrect implementations but also the correct implementations)? Also, provided you have a data structure that can represent money, you should presumably be able to serialize that data structure and store or send it just like any other data, right? W…
I never said you need special database or wire format. Maybe if you are using JSON, transfer monetary values as strings rather than decimal or float data types. Some databases can actually handle money, some don't. Those that do not, usually require you to store money as strings to not lose information. When you get warned by your DBA that the database can't do arithmetic on strings, tell them that "thank you, it cou…
Problems will arise when you'll do multiplicative operations on money, for instance when working out taxes. There are precise rounding rules to apply, and the solution is to tackle these issue one abstraction layer above, on the operations rather than the values, because some time you'll want to carry out rounding between each tax operation, sometimes at the end, on one line or on a whole batch of transactions.
Other problems you'll bump into is the asynchronous nature of money flows. You won't realize it with credit cards (well you'll figure it out soon enough when you'll stumble upon "race conditions"), but this becomes explicit when dealing with mandates, direct bank transfers or checks. You need to move the money out of sight of the user in a ledger specific to that person that holds transactions being processed (can takes days or weeks in some case) and move it back to the original ledger if the transaction fail. Otherwise you'll bump into issues of double spending. This is something that is out of your control sometimes (had the unfortunate experience to issue withdrawals multiple times on a big bank's payment processor API and theses dunces sent the money multiples times). Use idempotency keys profusely as well as (distributed) locks. The hardest part is not getting your part right, it's handling external actors bad implementations. Also fuck HTTP w/ hooks. Some actors do not even make sure you received the webhook. The non binary aspect of HTTP is a bullshit argument and I'd gladly trade it for a binary protocol that has strong quality of service mike MQTT, since anyway I'll have to implement some kind of smart broker when issuing orders to a shitty HTTP api anyway.
Re: 64-bit bank balances ‘ought to be enough for anybody’?
#109Earlier quoted context omitted.
Hypothetical solutions that do not exist are none of my concern. Did you know different countries and different currencies have different rounding rules, for example for tax-related calculations? Does "IEEE decimal128" support this? Unless you can get all countries on our planet to agree on a single standard, any solution that does not allow specifying rounding rules is pretty much useless (unless you want to impleme…
This is not hypothetical. Yes, of course IEEE decimal supports setting the rounding mode. The authors of the spec aren't ignorant of what's needed for financial and tax computations. Use fe_dec_setround from ISO/IEC TR 24732, "Extension for the programming language C to support decimal floating-point arithmetic". The modes listed at https://www.ibm.com/docs/en/zos/2.5.0?topic=functions-fe-dec... are: FE_DEC_DOWNWARD…
https://en.wikipedia.org/wiki/IEEE_754#Roundings_to_nearest
EDIT: apparently IEEE does not specify a "round-to-odd" for ties despite this having been used for banking in the UK :/
Re: 64-bit bank balances ‘ought to be enough for anybody’?
#110Specialising in financial software, over the past 2 decades I have been fighting over this with countless people, teams and companies. For accounting you should only ever use arbitrary precision math library with ability to specify rounding rules. If your programming environment/language does not have one, it is unsuitable to be used for accounting, billing, invoicing, payments, etc. Having the underlying library is,…
I have a personal anecdote on this subject. A long time ago I worked at a bank and I had to calculate a large number of accounts regarding agricultural loans. These were state sponsored loans. When I finished my task (this was a Java job), I found that sometimes the results were off by $0.01. So I asked my boss how I should do the rounding, to which he replied that an error of up to $1 was acceptable. If I recall cor…