Fixed – Fixed-place decimal math library for Go
github.com
github.com
1. If you are above 100 billion, you are probably dropping the the 'fractions' and dealing with whole numbers. Most databases don't have their columns configured as Decimal(64,64) for 128 digits. It's not practical. So I would store the amounts above 100 billion in another value - the billions unit. And if you are 100s of billion, I am pretty certain you're not concerned with .0000001 dollars. Most 'terminals/receipts' couldn't show/print a number that high without truncating or the UI/representation would be all messed up.
2. I don't believe the crypto-currency space needs more than 7 places on an exchange. The CME only supports 8 decimal places in their protocol. Most of these issues are handled by reinterpreting the scale & quantity. "The satoshi is currently the smallest unit of the bitcoin currency recorded on the block chain. It is a one hundred millionth of a single bitcoin (0.00000001 BTC)." and since there can only be 21 million BTC, it easily fits - although I would probably change the code to use 8 decimal places for ease of use.
3. I might add more rounding modes. They are trivial, but there are some pretty exotic ones - so implementing them all internally, rather than externally can be problematic.
4. For the gamers that say they need float32 - there are more digits of precision in Fixed that float32 - just change the number of places in the code... if you need less significand and more decimals.
5. I've added integer Mul. It is about 2x faster than using floating point. If you avoid limiting overflow, which it doesn't, it is closer to 10x.
Uint256 comes from the fact that it is native word size for EVM and that is because of crypto operations.
type Billions fixed.Fixed
and then add operators to allow Fixed to be added, String() would add a B at the end etc. So 0.1 is 100 million, etc.
Like I said, if you are summing into the billions, you are probably not concerned about .00001 pennies
Be careful with that logic. Salami fraud takes advantage of low precision. You need to maintain enough precision to make it not worthwhile for your transaction volume.
I think the core frustration is how values less than one are subject to about 1 million-billionth part of noise, which could be tolerated except that factors like inflation are recorded as fixed decimals.
For example, if monthly inflation is standardized as 5 significant digits, then for 0.0012345 - the rounding to 5 sd actually introduced about one hundred-thousandth part of noise to whatever the real value was, but the number is then considered precise. Subsequent encoding of 0.0012345 to a float Double is ten billion times less imprecise than the writing of 0.00123447... to 5 sd was, but it is an unwanted inconsistency that is difficult to securely keep out of the fixed point results, even though they are kept to much lower precision.
What experience do people who work in banks have?
However, if you're doing things like high-frequency trading systems or machine learning stuff with massive amounts of data, then performance really does matter, and using floating point is entirely reasonable. If you're making systems like that, you're hopefully aware of the limitations of floating point and know how to use them safely.
I never use floats for any quantities which i need to exactly add up to a known total, of course.
Running option trading models with BigDecimal is unproductive. However, when the calculations are done, we store the results back as decimal representation.
There are requirement time discussions/rules that indicate if a computation has a rounding rule or not (and it is normally driven by whether a calculation involves division, or if a computation must match an amount in a different currency).
Dividing amounts, as example, always comes about when there are mid-cycle cancelation/onboardings to a service.
Currency translations cause that as well.
You have to ask, what do you even mean if you use floating point for representing money?
If you use floating point, the whole point is that you want the behaviour
1e100 = 1e100 + 1
This is exactly what you want for many analysis and decision making problems, but it is a dangerous default.
If I am owed 2.575% on $3425956.57 for 245 months, why not get the correct sum instead of some rounded monthly sum added up? Its just strange.
Fractions do little for interest rates, which are transcendental functions and sometimes even irrational.
Your issue then is that if you combine a large enough number with anything, then you get precision loss and money just starts disappearing (or appearing out of nowhere).
Even if your hyperinflation was over ten orders of magnitude less bad than Zimbabwe's (decimal orders of magnitude even), you would run into floating point precision loss with a 64 bit floating point number.
Edit: Japan too.
Say south korea has a few years of hyperinflation, not even anywhere close to zimbabwe bad, and you'd have money disappearing right & left.
2.22 * 100.0 == 222.00000000000003, not 218.0. This is a) wrong and b) not an integer.
Either you are aware of this and manually round the result to an integer, or you use fixed-point math.
Explosion of storage space and computation complexity. When you combine real-world numbers with compound interest, every time you add the interest, you’re adding decimal digits to the value. For your example, after 245 months of compound interest at 2.575% per month, the value will have 1228 decimal digits in it, that’s more than 512 bytes to store and process.
Another reason is, for the last ~700 years, finance folks use this: https://en.wikipedia.org/wiki/Double-entry_bookkeeping_syste... With that system, coins allow for some kind of rolling checksum verification. BTW, in modern software, the coin is often $/€/whatever 0.0001.
This used to cause problems at a former workplace, because the "math" in the regulations around scheduling used tables, so the functions were highly non-linear, and less math savvy customers would complain that reversals of calculations wouldn't work as expected. If we had used continuous functions, it would have worked out, but then we would have been going against regulations.
Be glad we at least have a decimal based coinage system these days. We'd all have such fun dealing with fractions.
Ada had proper fixed point types in 1983 already, and added additional requirements for the implementation of decimal fixed point types as part of the 1995 language revision. Other languages ... may benefit from its example.
This would be essentially useless in game development (which is my field). In gamedev it's pretty much 32-bit floats all the way down, and very little else. Very small fixed point types are occasionally used in shaders (Cg provides a native 12-bit fixed point type) to represent colors, but a library like this is pretty much pointless.