Live data from Hacker News

64-bit bank balances ‘ought to be enough for anybody’?

tigerbeetle.com

21–30 of 372 posts

Re: 64-bit bank balances ‘ought to be enough for anybody’?

#21
post #3

Perhaps I'm the odd one out here, but most financial systems I've had the chance to work with don't actually use numeric types to store values, they use strings or other comparable types. Numeric values are passed to all outside interfaces, but the internal states are written in a way where no bit level issues peddle with the values. I'm wondering what the experience of the wider audience here is?

> internal states are written in a way where no bit level issues peddle with the values

... "bit level issues"? you eventually are going to need to use those bits to add, multiply, subtract or divide the numbers.

Using character strings to represent numbers is certainly one way to do arbitrary precision/ BigInteger (like the article describes). But you might want to postpone transcoding it to characters until you decide to export your numbers across a boundary. Otherwise all of the arithmetic operations you do have to suffer this round trip each time.

Re: 64-bit bank balances ‘ought to be enough for anybody’?

#22

I was under the impression that BCD was generally recommended for money, often because of (IEEE?) rounding and machine precision/epsilon: * https://en.wikipedia.org/wiki/Binary-coded_decimal * https://en.wikipedia.org/wiki/Machine_epsilon

I've never seen anyone use floating point for money in their bespoke applications

Every banking client did use double for the actual calculation phase of their derivatives trades.

(And some of our back-end systems then did ludicrous broken wrong-headed rounding to turn them into fictional currency values... Ho hum.)

Re: 64-bit bank balances ‘ought to be enough for anybody’?

#24
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, of course, not enough. You also need to be able to properly store (data structures, databases), transfer (wire formats, data structures), process (order of operations, rounding rules), present (UI toolkit) and so on.

I have never in my life joined a software project for any organisation that was able to do basic arithmetic on money correctly (and I worked for companies ranging from small startups just needing invoices and very simple billing to risk management departments for largest financial institutions on Earth processing trillions of dollars on a daily basis).

Re: 64-bit bank balances ‘ought to be enough for anybody’?

#25
post #9

Earlier quoted context omitted.

why add the complexity of bcd when you can just put in it units (e.g. cents) where there's no decimal point?

What do you do if heavy deflation causes the government to release a $0.001 coin? A cent isn't a fundamental unit. Edit: as another hypothetical, what if the $0.001 coin is released to support micropayment use cases?

These systems use something like 10^-8 as the implied decimal in the real world. Some forex exchanges even go to 10^-9

Re: 64-bit bank balances ‘ought to be enough for anybody’?

#26
post #6

Earlier quoted context omitted.

If you actually want to do something useful and accurate and auditable and performant and space-efficient, because you have a lot of money values to bank with, you really don't want too much abstraction. My experiences in various bits of banking include where juniors ignore advice NOT to store currency in floating point values and then come whining that arithmetic is broken, and tech dudes in a lab deciding that ever…

Floating point feels like an incredibly grokkable concept that was just not taught well for a long time. Maybe too mathematically (of course). Or maybe that was just my experience. I feel like any dev team should pick up a copy of this for on-boarding: https://jvns.ca/blog/2023/06/23/new-zine--how-integers-and-f...

Floating point being grokkable doesn’t make it any more suitable for this application.

Floating point is inherently an approximation - your bank balance should not be an approximation.

Re: 64-bit bank balances ‘ought to be enough for anybody’?

#27
post #9

Earlier quoted context omitted.

why add the complexity of bcd when you can just put in it units (e.g. cents) where there's no decimal point?

What do you do if heavy deflation causes the government to release a $0.001 coin? A cent isn't a fundamental unit. Edit: as another hypothetical, what if the $0.001 coin is released to support micropayment use cases?

In a situation like that I think it would be better to have the system not work until it’s fixed than to potentially lose precision and work with untested inputs

Re: 64-bit bank balances ‘ought to be enough for anybody’?

#28

I was under the impression that BCD was generally recommended for money, often because of (IEEE?) rounding and machine precision/epsilon: * https://en.wikipedia.org/wiki/Binary-coded_decimal * https://en.wikipedia.org/wiki/Machine_epsilon

I've never seen anyone use floating point for money in their bespoke applications

You _can_ use floating point if you are very careful and know what you are doing and know about decimal normalization (see e.g. OpenHFT implementation for high-frequency trading: https://github.com/OpenHFT/Chronicle-Core/blob/ea/src/main/j...)

But if you are not an expert, you better stick to BigDecimal and absorb the performance costs.

Re: 64-bit bank balances ‘ought to be enough for anybody’?

#30
post #3

Perhaps I'm the odd one out here, but most financial systems I've had the chance to work with don't actually use numeric types to store values, they use strings or other comparable types. Numeric values are passed to all outside interfaces, but the internal states are written in a way where no bit level issues peddle with the values. I'm wondering what the experience of the wider audience here is?

If by "bit-level issues" you mean bit flips (which you should be worried about), a string doesn't help much - "4" is 0x34 ASCII/UTF-8, flip lowest bit and you get "5" (0x35). I'd imagine if I have to protect against bit-level fuckery something like this would be a better representation: struct Dough { u64 amount; u64 amount_again; u64 amount_just_to_be_really_sure; } that and hardware-level protection of course

Storing the same element the same way isn't really helping against implementation bugs, if going that route, better store in multiple formats (u64, int, or string), to protect yourself from a CPU or interpreter or library bug. In practice, just store the amounts as integer, and if you are really worried, add a checksum (if total balance is not enough).
Post reply on HN