5 ms·
I think that's the disconnect here — 'high' finance is not an exact science, and clients don't actually have an easy way of checking the numbers directly themse
by smallnamespace 8y ago
I think that's the disconnect here — 'high' finance is not an exact science, and clients don't actually have an easy way of checking the numbers directly themselves — not only the models, but the inputs are also proprietary. Even auditors and regulators are dependent on bank models.
Note that the article's advice is to use their own library, but the library just uses JS floats as ints and a separate precision arg:
https://github.com/sarahdayan/dinero.js/blob/master/src/dinero.js#L47 https://github.com/sarahdayan/dinero.js/blob/master/src/dine...
This doesn't give you any more precision than using floats directly, just a wider 'mantissa' range.
- kbenson 8y agoI thought it was fairly obvious I wasn't talking about banking. I was providing an example of a much more common scenario, which many businesses have to deal with, that also provides a good reason for taking care with currency. > This doesn't give you any more precision than using floats directly, just a wider 'mantissa' range. Floating point errors sometimes result in slightly smaller values than expected, and this can result in problems when they are passed around if even one spot if missed that needs to round. For example, some databases might truncate 1.9999999999 to 1.99 instead of round to 2.00. As a simple illustration, consider the following Javascript (because it's easily available): price1 = 0.10; price2 = 0.20; package1 = price1 + price2; // Hmm, 0.30000000000000004 on my system ten_packages = 10*package1 money_received = 5.00; change_due = money_received - ten_packages; // change_due is 1.9999999999999996,should be 2.00 So, either you choose floating point, and make sure to always round prior to display or passing to any other system and if you miss a spot it will probably just work fine until you hit specific values, or you convert to cents, and you only have to worry about overflow, and any place you don't convert is obvious because it's not formatted with cents and is an order of magnitude too large. And if you're worried that an int is too small and might overflow, just use a long, and that problem goes away for all conceivable real values in your lifetime. If you're coding defensively (and we're talking about money here, so why wouldn't you be?), one of them is obviously a better choice
- smallnamespace 8y ago> I thought it was fairly obvious I wasn't talking about banking Right, but the article is talking about all use cases of currency... not all of which have customers that care about penny precision. I think we're in agreement that the business use case should be driving the technical requirements, and sometimes software engineers overestimate the precision actually necessary. Overflow modes aren't always consistent between all your systems either, so I think in practice, fixnums also have issues and the advantage isn't totally clearcut. > always round prior to display or passing to any other system This rather depends on how much control you have over the other systems. Since, you're basically throwing away precision every time you round, it's preferable to use floats to pass data back and forth and only round before you display. I mean in practice, you should be using formatted outputs (whether printf format strings or something fancier) to show monetary amounts, and those should be doing rounding automatically.
- kbenson 8y ago> not all of which have customers that care about penny precision. No, I think all customers care about penny precision when you are talking about money they have or owe. Either the amounts in question are small enough that a penny isn't negligible, even if it's not important, or the amounts are large enough that an error like that really shouldn't exist, because they should be taking it very seriously. People might be willing to let it go because it's a small amount, but they'll remember it. > Overflow modes aren't always consistent between all your systems either, so I think in practice, fixnums also have issues and the advantage isn't totally clearcut. They're consistent in that it's generally trivial to allocate enough bits to it that an overflow can't happen in any sane inputs. As opposed to floating point, where errors happen throughout the entire range of sane inputs. > Since, you're basically throwing away precision every time you round, it's preferable to use floats to pass data back and forth and only round before you display. No, you're generally not throwing out precision when you round in this case. You're throwing out error. If you apply a percentage to money, they you might be throwing out precision, and that's a case you should think about. But for currencies any time you round you are purely fixing floating point errors that comes naturally by mixing number bases in this way. > t's preferable to use floats to pass data back and forth and only round before you display. You are explicitly saying it's preferable to use a lossy encoding for pass data back and forth because as long as you remember to do so there's a fairly easy way to recover the loss. the question remains, why is that preferably to using a medium that isn't lossy for any sane input you could want to represent?
- naranha 8y agoI think you are right. I also worked on a bill-tracking software and one of the first things we noticed is that each company has their own way of rounding totals. There is no one correct way. For example one company rounds each line to three digits internally for the total but prints only two digits on each line. For my software I started using decimaljs for the highest precision but in the end it never made any difference cent wise even when the payments go in the millions.
- haberman 8y ago> This doesn't give you any more precision than using floats directly, just a wider 'mantissa' range. I think this analysis misses a deep and important point. The library you linked uses decimal floating point (in software) instead of the binary floating point used by IEEE floats. The point of this is not to increase overall precision. A double is already precise to 2e-14% of its value, which means it's capable of representing something like $1 Trillion before it will get off by a whole cent. The point of using decimal floating point is that it can exactly represent the values we care about when dealing with currency. This allows us to have no error, instead of trying to keep our error small. It means we never have to round (unless performing division). You could have 1000x the precision in binary floating point, and decimal floating point would still be better for money.
- smallnamespace 8y ago> This allows us to have no error That's not true, because the software 'mantissa' in that library still only has 52 bits of precision (2e-14%). E.g. if you try to add $100 trillion + $0.01 using dinero.js, you still get underflow and the $0.01 disappears.