News for hackers. Stuff that matters.
Re:0.30000000000000004 by _bxg1 on Monday December 02, 2019 @04:20PM (#21687077)
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.
Re:0.30000000000000004 by nwallin on Monday December 02, 2019 @05:20PM (#21687687)
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*.

Re:0.30000000000000004 by code_code on Monday December 02, 2019 @08:20PM (#21689034)
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.
Re:0.30000000000000004 by hnzix on Monday December 02, 2019 @07:19PM (#21688615)
> make a lot of assumptions about other peoples' domains and we're wrong a lot

What do you mean this person has no surname? That's unpossible, surname is never null, error error.

Re:0.30000000000000004 by bwilliams18 on Monday December 02, 2019 @04:26PM (#21687138)
US currency can go to more than two decimal places...

http://blogs.reuters.com/ben-walsh/2013/11/18/do-stocks-real...

I guess it's time for someone to write an "Assumptions Programmers make about money" post.

Re:0.30000000000000004 by raarts on Monday December 02, 2019 @05:03PM (#21687527)
Falsehoods programmers believe about prices: https://gist.github.com/rgs/6509585
Re:0.30000000000000004 by raverbashing on Monday December 02, 2019 @05:11PM (#21687599)
Interesting list, though I'm not sure what do they mean by n. 7
Re:0.30000000000000004 by jsjohnst on Monday December 02, 2019 @06:13PM (#21688124)
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.
Re:0.30000000000000004 by jjeaff on Monday December 02, 2019 @07:15PM (#21688577)
I also have a few. You could buy a stack of 100 trillion dollar bills few a few bucks then. They are now selling for $50-$60 on eBay.
Re:0.30000000000000004 by boomlinde on Tuesday December 03, 2019 @04:02AM (#21690937)
Investing in ZWL, bold move!
Re:0.30000000000000004 by raarts on Monday December 02, 2019 @05:23PM (#21687720)
Re:0.30000000000000004 by LanceH on Monday December 02, 2019 @04:33PM (#21687210)
1. Money in a brokerage account is not US currency.
Re:0.30000000000000004 by zrobotics on Monday December 02, 2019 @05:02PM (#21687515)
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.

Re:0.30000000000000004 by F-0X on Monday December 02, 2019 @04:57PM (#21687466)
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).
Re:0.30000000000000004 by blowski on Monday December 02, 2019 @05:16PM (#21687653)
How do you store Bitcoin?
Re:0.30000000000000004 by zelly on Monday December 02, 2019 @07:14PM (#21688568)
Bitcoin uses fixed-width unsigned integers. The smallest unit is 10^-8 of 1 Bitcoin, which is represented as just 1.
Re:0.30000000000000004 by blowski on Tuesday December 03, 2019 @03:52AM (#21690897)
I like this approach. Is it compatible with the parent comment?
Re:0.30000000000000004 by zelly on Tuesday December 03, 2019 @10:42AM (#21693276)
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.
Re:0.30000000000000004 by nitwit005 on Monday December 02, 2019 @04:45PM (#21687346)
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.
Re:0.30000000000000004 by ars on Monday December 02, 2019 @04:54PM (#21687435)
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.

Re:0.30000000000000004 by jcranmer on Monday December 02, 2019 @05:03PM (#21687524)
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.
Re:0.30000000000000004 by coldtea on Monday December 02, 2019 @05:33PM (#21687818)
>Someone should tell that to everyone who ever used a ½¢ coin in the US.

All 10 of them?

Re:0.30000000000000004 by jsjohnst on Monday December 02, 2019 @06:15PM (#21688144)
I’ve got some at home, but admittedly I’d never use one as currency. I also have US ½¢ paper notes too.
Re:0.30000000000000004 by nitwit005 on Monday December 02, 2019 @05:29PM (#21687775)
Go to a bank and ask for a half penny or a thousandth of a dollar. Let me know how it goes.
Re:0.30000000000000004 by jsjohnst on Monday December 02, 2019 @06:17PM (#21688171)
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.
Re:0.30000000000000004 by nitwit005 on Monday December 02, 2019 @06:26PM (#21688248)
Because, unlike a thousandth of a dollar, those are valid amounts for real transactions.

It goes without saying that half pennies are dead. A mill seems to be from the Coinage Act of 1792, which is perhaps a tad outdated.

Re:0.30000000000000004 by jsjohnst on Monday December 02, 2019 @06:35PM (#21688304)
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.

Re:0.30000000000000004 by cellular on Monday December 02, 2019 @07:48PM (#21688806)
I pull the gas lever intermittently until the gal goes up but the cents don't. It takes about 5 tries, but always makes me smile that I beat the game.
Re:0.30000000000000004 by monster_group on Monday December 02, 2019 @04:23PM (#21687102)
>>...since for example US currency only ever goes to two decimal places

That is not correct. Stock settlement transactions often list four decimal places.

Re:0.30000000000000004 by maltalex on Monday December 02, 2019 @04:34PM (#21687222)
> Stock settlement transactions often list four decimal places.

That's not a significant difference compared to two decimal places, so brundolf's point still stands. There's no need for arbitrary precision.

Just store all dollars in PIPs so 5$ will be stored as 50000.

Re:0.30000000000000004 by tombert on Monday December 02, 2019 @04:36PM (#21687244)
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.

Re:0.30000000000000004 by dorgo on Monday December 02, 2019 @05:14PM (#21687638)
Google uses 1000000 as multiplier in their APIs.

Edit: And they forbid equality comparisons for rationals. For some reason even >= is not allowed.

Re:0.30000000000000004 by tombert on Monday December 02, 2019 @05:19PM (#21687684)
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 :) ).
Re:0.30000000000000004 by PeterStuer on Monday December 02, 2019 @05:15PM (#21687643)
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.
Re:0.30000000000000004 by drdrey on Monday December 02, 2019 @04:42PM (#21687308)
Counterexample: gas prices in the US are frequently displayed with 3 decimals (tenth of cents)
Re:0.30000000000000004 by salty_biscuits on Monday December 02, 2019 @04:51PM (#21687406)
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.
Re:0.30000000000000004 by TeMPOraL on Monday December 02, 2019 @06:10PM (#21688102)
So how much do 2 CCs of gasoline cost?
Re:0.30000000000000004 by hrktb on Monday December 02, 2019 @04:49PM (#21687378)
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.