I haven't worked in fintech but I've read that money is often represented (at least in storage) as plain integers, since for example US currency only ever goes to two decimal places. But I guess once you start operating on it you run into potential truncation unless you use rationals.
In finance, US dollars are generally stored to four decimal places, because you need to deal with stuff like compounding interest or stock splits.
COBOL has a built in fixed point integer type, which makes defining a 4 digit decimal and doing math on it easy. (IBM designed it from the ground up to cater to people with a lot of money, who spend a lot of money, to work with lots of money, ie banks) Java has the BigDecimal type, which is a class in the class library, which means you need to import it. And because Java lacks operator overloading, doing calculations is tedious.
In the 90s, there was a huge push to replace COBOL with <something else>, and Java was the Rust of its day, so that's what everyone got behind. However, 4 digit COBOL decimals apparently round differently than 4 digit Java BigDecimals, so all the tests failed. And all the stuff like a\x+b had to be written like BigDecimal.add(BigDecimal.multiply(a,x),b) so development was taking forever.
Eventually they said "fuck it" and 20 years later we're still stuck with COBOL and everyone who remembers the original death march says "never again".
I have a feeling a lot of the problems came down to computer science people thinking money has two decimal digits but domain knowledge people knowing it has four. We programmers, as a group, make a lot of assumptions about other peoples' domains and we're wrong a lot*.
I've had the thought that programmers should note assumptions in flagged comments, and those comments should be automatically collected, and then reviewed occasionally. Assumptions might be sustainable, so to speak, but they can also create one kind of technical debt.
For a brief time in 2008, 1 Zimbabwe dollar was very roughly equivalent to one TRILLIONTH of a United State penny. So technically a value of “1” did exist, but it was meaningless. I have some of the 100 Trillion Dollar notes from Zimbabwe from that time period.
While it isn't physical US currency, my brokerage account represents the value of the account in units of USD- therefore any rules about how US currency works should apply.
Additionally, fractional cents are often presented to the consumer when purchasing gas/fuel.
Money is not as wierd as anyone might guess. I work on a financial application, and money is almost always just a BigDecimal with the scale set to 2 (and stored in a database as a bigint type or equivalent). When its not, its just a higher scale (for say, compound daily interest on small amounts for a significant period of time).
Yes, the parent approach is the same thing but with a decimal point added for convenience. The main thing is that the scale is fixed; it is effectively an integer count of 1s of the least significant index. It is impossible to truncate values or round upward and create money that didn't exist. This makes it perfect for representing actual money.
No it can't. There are systems that track things worth less than a penny for later billing, but at the end of the month when they bill someone, they do some sort of rounding.
If you are earning interest at a bank, and you've earned a fraction of a penny, they will eventually pay it to you once you've earned enough for a whole penny.
i.e. they track your account balance to more than 2 digits, they just only show you 2 digits.
Someone should tell that to everyone who ever used a ½¢ coin in the US. Also, US law explicitly states (31 USC §5101) that the unit of 1/1000th of a dollar is a mill.
Go to a bank and ask for a $500 or $1000 note too. They won’t give you one as they aren’t in circulation anymore, but most (all?) will let you deposit it for face value.
Take two half penny coins or notes to the bank and they’ll credit your account a penny. Of course, just like with the $500 or $1000 notes, you’ll be losing money on the deal.
> A mill ... is perhaps a tad outdated.
Yet you use mills every time you pay for gas. Pointless in that case? Probably. Still used all the time? Certainly.
You can still get reasonable enough approximations with more than two decimals if you do something like `int64 myWorkingMoneyVal = currentMoney * 100000`, do your work, then divide the final result by 100000. You still risk some potential truncation if your work involves division, but the larger your multiplier that you're working with, the larger divisor at the end, which will help minimize how much of an error this ends up being. The 64 bit integer space is pretty darn big, so you typically don't risk an overflow, and you will typically get better performance than using a regular "decimal" type, since on-chip integer operations are usually very fast.
EDIT:
Just a note, there's nothing special about the number 100000; pick the largest exponent of 10 that you can get away with a reasonable assurance that no overflow is possible. For a vast majority of money applications, I seriously doubt you're going to be hitting the limits of int64, so you could probably even get away with something like 1000000000.
I didn't know that, but it doesn't surprise me (I suspected I wasn't the first person to come to the realization that there's no reason not to choose a giant number :) ).
I have developed a payment plan calculator for asset based finance and you would be amazed how many different rounding schemes and day counters (for fractional periods) exist and are actively used.
It isn't really a price though, it is a rate for an infinitely divisible good, i. e. $/L. You get the price when you multiply with the quantity purchased.
The basic representation is usually good enough at 2 decimals (so a plain int), but it is often needed to have a transient representation during calculations.
For instance if one needs to apply discounts, add taxes, split in equal parts, all of the above one after the other, there will be a more precise intermediary representation before rounding everything in a way that keeps the total amount consistent with the original amount.