5 ms·
Nice. It is unbelievable that none of today's widely used programming has standard support for handling money correctly. I don't want to know how many programs
by usr1106 9y ago
Nice. It is unbelievable that none of today's widely used programming has standard support for handling money correctly. I don't want to know how many programs use (binary) floating point to do it.
(Disclaimer: I don't work with any financial figures and I have not checked whether the dec64 proposal is a sound one.)
- rwallace 9y agoJava and Python, for a start, have decimal number types in their standard distributions.
- QasimK 9y agoPerhaps he means that by default money will be handled incorrectly.
- wereHamster 9y agoIn Haskell you'd use Fixed (https://hackage.haskell.org/package/base-4.10.1.0/docs/Data-Fixed.html https://hackage.haskell.org/package/base-4.10.1.0/docs/Data-...) with your desired precision (E2 for most currencies). It's in base, so no third-party libraries are required.
- sadiuasdi67f678 9y agoIn Java, the java.math.BigDecimal is not a primitive data type. It also has an awkward api due to lack of operator overloading (thanks to BigDecimal not being a primitive data type it seems). In Python, the story looks slightly better: from decimal import * >>> getcontext().prec = 6 >>> Decimal(1) / Decimal(7) Decimal('0.142857') But neither of these data types is even close to being a first class citizen in either language.
- usr1106 9y ago.getcontext().prec = 6 makes no sense for money. You need 2 digits after the decimal point constantly, whether it is 0.01 or 1000000.01 AFAIK (and I don't do this for work), after every calculation you manually need to call quantize as in cents = decimal.Decimal('.01') money = price.quantize(cents, decimal.ROUND_HALF_UP)
- sadiuasdi67f678 9y agoI'm not talking about money, I am talking about the decimal data type, as is OP. https://en.wikipedia.org/wiki/Decimal_data_type https://en.wikipedia.org/wiki/Decimal_data_type Also, I don't try to endorse the Python API. I don't even use it. I just pointed out their api is easier since the operators work with their decimal data type, as opposed to the Java version.
- the-dude 9y agoHow would you handle prices for components which do have more significant digits than 2? ( I have examples if you wish ).
- usr1106 9y agoOf course more digits than 2 exists. In Germany petrol/gas has always been priced with 3 decimals. And in B2B it's even more common. I'm talking about 98% of consumer business where the precision is full cents for each transaction. In general you need to know when to round and to how many digits. But my complaint was that languages have a natural API for binary floating point, which is useful for scientific number crunching, but rarely anything comparable for commercial calculations. I have not tried to design a natural API for fixed (but parameterizable) decimal precision and the implicit rounding required. But I would be surprised if it's impossible to come up with anything less verbose (explicit constructors everywhere) and less error prone (forgetting to call rounding).
- rwallace 9y agoWell that's true, and if you're going to argue that the lack of equally or more concise syntactic support is an omission, I agree. I think 1.23 should denote a decimal floating point constant, and a special suffix should be required if you want to use binary. But I think it's important to make sure programmers don't end up with the idea that they might as well store money amounts in binary floating point because the language they are using doesn't support decimal.
- alkonaut 9y ago.NET at least made it a primitive, with operators and stack allocation. I had forgotten how terrible this is in Java.
- maltalex 9y ago> In Java, the java.math.BigDecimal is not a primitive data type. It also has an awkward api due to lack of operator overloading (thanks to BigDecimal not being a primitive data type it seems). If you're on the JVM, Groovy is nicer in that regard. It uses by default BigDecimal and BigInteger for literal numeric types, and has operator overloading: http://groovy-lang.org/syntax.html http://groovy-lang.org/syntax.html
- vorg 9y ago> It uses by default BigDecimal and BigInteger for literal numeric types Apache Groovy uses by default BigDecimal for literal decimal types, but only uses BigInteger for literal integral types when it would overflow the largest available primitive type for that literal. You can force a BigInteger by using the suffix `g` on the integral literal. Perhaps misunderstanding this is the source of some hard-to-find bugs in some of your Groovy code.
- aldanor 9y agoToo bad there isn’t one in C++ — everyone rolls their own. Would really make sense to have it as part of STL.
- camgunz 9y agoThere are arbitrary-precision math packages: gmp and MPFR are the big ones, MPDecimal is what Python uses but is in C, etc.
- SuddsMcDuff 9y ago.NET has it's System.Decimal type specifically for this purpose - (https://msdn.microsoft.com/en-us/library/system.decimal(v=vs.110).aspx#Anchor_6 https://msdn.microsoft.com/en-us/library/system.decimal(v=vs...)
- andromeduck 9y agoWhat's wrong with just using a u64?
- usr1106 9y agoYes, storing everything in cents and format a decimal separator (which is a localization mess https://en.wikipedia.org/wiki/Decimal_separator https://en.wikipedia.org/wiki/Decimal_separator ) before any output is one option. That works fine for addition and subtraction. When you divide (or do percent calculations) integer cents is no longer, you need to deal with rounding manually/some custom class with every calculation.
- andromeduck 9y agoYeah but that's rounding error which isn't limited to just money. There's no universal precision/representation between all the currencies an currencies change all the time so it would be wildly inappropriate to bake into a programming (language?) standard. Also, what's with the aversion to traits/types? This is the whole point of having operators/types.
- usr1106 9y agoCorrect. Precision must be parameterized for every variable. 2 is the most commonly used value (for money), but not the only reasonable one. And rounding needs to be done at certain steps but not a others. Typically internal calculations are expected to be done with maximum precision, and every time you have an item visible to the customer you round. Often to full cents, but there are cases where you show a fixed number of decimal cents even to the customer. I doubt that cases where you show maximum precision to a customer are common.
- wiz21c 9y agoProblem is that code is written by many people, so you have to agree on a way to divide (for example). Then, it means that you have to enforce the way you code it and current standard programming languages (python, java, c,...) don't help you there. We need a decimal format because people who read the code are sometimes not coders how know about the various tricks to pack decimals in uint64. So, u64 is perfectly doable, sure, but it doesn't scale with the various types of people who write/read the code. (same thing for floats : you can do money computations with them, but that'll work only if the people understand the trade offs of the representation; and believe me, they're not legions)
- wsc981 9y agoAlso Objective-C and Swift have decimal types. Though they are a bit unwieldy to use (at least in Objective-C, possibly in Swift).
- alkonaut 9y agoLanguages* (or “platforms”) have decimal types. Or you can use integers and agree on a normalization (such as cents or 1/1000 of a cent). Because languages* also have integers. *Ok not that one.
- walshemj 9y agoCOBOL does I seem to recall
- bcatanzaro 9y agoThe databases have number formats that represent numerical values for money correctly. And they’re probably the most widely used programming systems for dealing with money. https://dev.mysql.com/doc/refman/5.7/en/fixed-point-types.html https://dev.mysql.com/doc/refman/5.7/en/fixed-point-types.ht...
- usr1106 9y agoCorrect. But databases are not programming languages. I have never done any SW development in the commercial domain. Do you say in banking system the amounts never make it to the host language, they are always calculated in the database? A cashier system most likely doesn't even have a database. At least not used for every item.
- bcatanzaro 9y agoI'd count SQL as a programming language. https://en.wikipedia.org/wiki/SQL https://en.wikipedia.org/wiki/SQL
- usr1106 9y agoBut my main question was: The system that handles my bank account is it written in SQL only (or mainly)? I really don't know, because I have never seen the source code of such a system. For the average cashier / checkout system I would doubt that, although again I have never seen the source.
- olliej 9y agoIeee 754-2008 defines decimal floating point with sound specifications for rounding and arithmetic. It’s provided in most higher level environments these days (java, .net - where I think it might even be a vm primitive?) I still question the value of it but it does allow “perfect” representation of values common in decimal systems. But by the same token it can’t represent everything in all other bases. Shrug.