11 ms·
This is why when doing currency, you store in the lowest denomination possible and use whole number (if doing dollars, store cents in integers)
by AtheistOfFail 10y ago
This is why when doing currency, you store in the lowest denomination possible and use whole number (if doing dollars, store cents in integers)
- mikeash 10y agoExactly. (And yes, it's good to point out the right way, not just the wrong way!) I've heard of some applications using tenths of a cent since they needed more precision. For Bitcoin applications, I think you'd want to work in integer satoshis.
- Declanomous 10y agoThe default currency type I've seen used for accounting is a decimal with 4 digits trailing the decimal. I forget the leading digits, but it is something like 14. Basically I think the idea with 4 digits after the decimal is that the smallest denomination you can have is 1 penny, and that allows you to calculate percentages of pennies accurately to a hundredth of a percentage point.
- andrepd 10y agoWhat if you have to calculate, say, a 0.5% fee on a few satoshis?
- AtheistOfFail 10y agoCalculate it and round it off after calculation to the nearest satoshi.
- danbruc 10y agoThat does not solve the problem in general, you still may end up with fractional quantities if you, for example, calculate a 1% fee. The correct way to do it is to use a decimal floating point format AND carefully pay attention to rounding. Also note the the way you round usually depends on the context, for some calculations you want to round up, for some down, and for some in yet another way. So you perform explicit rounding with an explicit rounding mode everywhere it is required and don't assume that implicit rounding or the default rounding mode will do the right thing because they won't in general. EDIT: To expand a bit on the context. If you, for example, charge a percentage fee you can choose between rounding up getting at least the fee you are asking for or rounding down not charging the customer more than you are asking for. Or you can try to be less biased and round either up or down depending on the fractional part. This may still require tie-breaking, either in a direction of your choice, or randomized, or by some rule like round half to even. Different choices will obviously have different biases. While this may almost seem somewhat pedantic, such things have been exploited, see for example »Computer Capers: Tales of Electronic Thievery, Embezzlement & Fraud«. [1][2] Also note that there may be even legal regulations prescribing how you can and can not round, for example between the Euro and the replaced national currencies. [3] I also have some faint memories of a case against someone systematically exploiting rounding errors but I can not come up with a reference and may even misremember this. [1] http://www.snopes.com/business/bank/salami.asp http://www.snopes.com/business/bank/salami.asp [2] https://www.amazon.com/Computer-Capers-Electronic-Thievery-Embezzlement/dp/069001743X https://www.amazon.com/Computer-Capers-Electronic-Thievery-E... [3] http://www.sysmod.com/eurofaq.htm#ROUNDING http://www.sysmod.com/eurofaq.htm#ROUNDING
- deleted 10y ago[deleted]
- deleted 10y ago[deleted]
- mikeash 10y agoWon't decimal floats still result in errors like this if the absolute value gets too large? You can avoid that by ensuring that the mantissa has enough digits to hold the largest value you'll ever encounter with enough significance to represent the smallest value you'll ever encounter, but at that point you might as well use an integer with that smallest value as the unit.
- danbruc 10y agoOf course, you can push any system to its limits and you can certainly replace your calculations with integer arithmetics. But why would you? Decimal floating point types are readily available and usually offer enough range and precision for all practical purposes. So why reinvent the wheel? And just imagine the pain you are going to go through if you have to adjust your base denomination, say because the law suddenly requires two additional digits of precision. You will have to touch every number you ever stored somewhere. Someone else in the comments mentioned arbitrary precision arithmetics, but even those don't solve all your problems magically. Not only are they comparatively slow and more cumbersome to deal with due to their variable length nature, but they still fail to correctly deal with one third, so rounding will still be required unless you manage to avoid all the bad numbers. You may then be tempted to switch to a rational number type with arbitrary precision integers as numerator and denominator. But while you now solved the problem with the one third, you still have to approximate irrational numbers and transcendental functions, for example Euler's constant, which is not unlikely to appear in interest calculations. So you still have to think about rounding, even if possibly in less places.
- mhluongo 10y agoUse fixed-point decimal math.
- 10y ago
- SolarNet 10y agoOr use a language with arbitrary precision numbers (they are only like 50 years old so I can see why many people don't use them /s). As someone else already pointed out, this still prevents calculations of fees as a percentage, and other issues.
- waqf 10y agoC'mon, the Egyptians had arbitrary precision numbers.
- mikeash 10y agoDon't you still have to be smart about rounding at some point? Otherwise compounding a (say) 1% fee will lead to arbitrarily long numbers.
- SolarNet 10y agoYes. But then you write that at the boundary. Along with the other consistency checks. And you are forced to think about it at the appropriate time, instead of forgetting about it entirely (floats) or introducing subtle errors (integers, and then likely casting it to a float to calculate 1% and then adding it back by casting back to an integer; hint: that's also a bad idea because it has floats in it - which as we've learned recently on HN - are not that deterministic or precise).
- mikeash 10y agoLet's say you're not a complete idiot and avoid the use of floats altogether, what subtle errors would you avoid by using arbitrary precision numbers over integers?
- SolarNet 10y agoWell first riddle me this. How do you calculate a ⅓% (1 / 3 of a percent) fee with integers. Depending on your choice of solution I can tell you how it has a problem and how arbitrary precision numbers would solve it.
- sp332 10y agoI think banks keep track of calculations (like interest) down to the 4th decimal place, 1/10,000 of a penny. Then they round to the nearest cent when settling.
- cwmma 10y agothe lowest denomination of the dollar is the mill not the cent.
- spc476 10y agoThere are still items in the US that use mills (1/1000 of a dollar). Two examples: property tax and gas.