19 ms·
DEC64: Decimal Floating Point
- saagarjha 9y ago> DEC64 is intended to be the only number type in the next generation of application programming languages. Sure, but to get there it'd need to interface with the current generation of languages which still use double.
- usr1106 9y agoNice. 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.
- 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.
- macdice 9y agoHow does this relate to https://en.wikipedia.org/wiki/IEEE_754 https://en.wikipedia.org/wiki/IEEE_754 (2008 edition) which added decimal floating point in a couple of sizes including 64 bit? It's strange to publish something in the same space without any reference to that. It appears to be incompatible (IEEE 754 decimal64 has 53 bits of significand and 11 bits of exponent; this thing has 56 bits and 8). How is that helpful?! Libraries and hardware supporting IEEE 754 exist. What am I missing? Edit: it does say "A later revision of IEEE 754 attempted to remedy this, but the formats it recommended were so inefficient that it has not found much acceptance." at the end. Hmm.
- TimMurnaghan 9y ago> DEC64 is intended to be the only number type in the next generation of application programming languages. Intended by whom? A lone voice (however correct), a standards body, or an industry consortium? This article should really carry some authorship information.
- ballenf 9y agoI believe its Douglas Crockford: https://github.com/douglascrockford/DEC64 https://github.com/douglascrockford/DEC64
- tsenart 9y agohttp://blog.aventine.se/2014/03/09/a-silly-review-of-dec64.html http://blog.aventine.se/2014/03/09/a-silly-review-of-dec64.h...
- 84Winston 9y ago>Incidentally, binary floating point can also represent almost 16 (roughly 15.955) decimal places accurately That's false. The author do not understand the limitations of binary floating point. 0.2 is a periodic number in binary floating point. People need to first understand why 0.2 is a periodic number in binary floating point before writing a blog post.
- BlackFingolfin 9y agoI see no contradiction here, as long as the period is >= 16...
- wilun 9y agoYep, it seems people need to understand the details of base translation before writing a comment :p Anyway, IIRC you can round-trip 15 decimal digits correctly with an IEEE double. Don't know if it's floor(15.955) or something else, but it's close enough for me to consider DEC64 quite useless compared to existing, quite well-designed and widely used implementation of FP.
- cornholio 9y agoThe flaws raised three years ago when it was posted to HN are still relevant: https://news.ycombinator.com/item?id=7365812 https://news.ycombinator.com/item?id=7365812
- moneytalks 9y agoThe desperate clinging to a numeric system oriented to the binary internals of a computer in the human interface to those internals is insane. Choosing base 2 numeric systems as the default number system in any high level language is just shortsighted and stupid. Maybe DEC64 is flawed, but can we stop pretending that we like binary-based default systems for any reason other than the barrier to entry it creates for newcomers and visceral feeling of communing with computer internals. Binary has a place -- in low-level languages. Like assembler. There's nothing wrong with any language providing a non-decimal system as an optional number type. The system we have in many high-level languages is a frankenstein of a binary system that you usually interact with through decimal representation. The proposal gets at least one thing right: the languages of the future will have a numeric system default that has less insanity. But it will take the passing of a generation or two of developers.
- otabdeveloper2 9y agoThere's no such thing as a "binary" or "decimal" number. In the real world, there are natural numbers, integers, rationals and real numbers. Computer languages are designed with types that mimic this real-world number stack. Low-level binary implementation details don't leak unless you're overflowing or using bit operations. What you're really complaining about is the fact that rationals aren't a first-class type in any popular language. With that I agree, it's a shame that corners were cut we three number types instead of four.
- poizan42 9y ago> What you're really complaining about is the fact that rationals aren't a first-class type in any popular language They are at least in Clojure, which seems quite popular.
- baobrien 9y agoThis has got to be very slow, both in hardware and software implementations, compared to IEEE packed decimal float. Addition and subtraction on anything other than matched exponents is going to need rounds of multiplication-by-10, however you implement it. Using IEEE-754 packed decimal, you only need a handful of gates per digit to unpack into BCD.
- Veedrac 9y ago> both in hardware and software implementations Software multiplication is pretty fast? BCD is comparatively hard to do in software.
- garmaine 9y agoThe most important part of IEEE decimal arithmetic is the (weakened, made optional) mandate that decimal floating point perform exact arithmetic— deterministic cross platform results on the same inputs. This is important not just for financial accounting which motivated this departure from binary floating point (where error is tolerated), but for any distributed system that needs reliable computation in the presence of heterogeneous hardware or compiler optimizations. It is embarrassing that we live with this state of affairs in 2018 with no way to do deterministic/ exact real number arithmetic in programs without emulating the FPU in software.
- wilun 9y agoIEEE binary floating point is deterministic. There is no such thing as tolerated errors in compliant implementations. Non-compliant implementations are widespread for performance reasons, but that is a completely different story. Also I'm not sure about GPU, but FPU are typically compliant in HW, and it is typically the compilers that have faster approximate modes, and I think for mainstream ones only when you explicitly enable such optimizations, which are disabled by default.
- stephencanon 9y agoIf you want a default decimal floating-point type, the only defensible choice is the decimal128 type standardized by IEEE 754. It has a fully-defined arithmetic, specified by experts who have spent their careers thinking about the issues involved, and is wide enough to exactly represent the US national debt in every currency used on earth. There are situations where other decimal floating-point types are appropriate, but if you do not understand the tradeoffs you are making, you should be using decimal128. I don't agree with everything in Jens Nockert's "silly review", but he's right about a lot of things: http://blog.aventine.se/2014/03/09/a-silly-review-of-dec64.html http://blog.aventine.se/2014/03/09/a-silly-review-of-dec64.h... I made a few notes the last time I saw this type come up somewhere: - It has significantly less exponent range than IEEE decimal64 (it effectively throws away almost three bits in order to have the exponent fit in a byte; 2^56 is ~7.2E16, which means that it can represent some, but not all, 17-digit significands; the effective working precision is 16 digits, which actually requires only ~53.15 bits). - Even if you weren’t going to use those extra bits for exponent, they could be profitably used for other purposes. - Lack of infinity is a mild annoyance. - Rounding is biased for add/sub/mul, broken for divide. - It's not significantly more computationally efficient than the IEEE formats, despite handwaving by the author. ---- Edit: I would be remiss not to note that Intel has made available a well-tested complete implementation of IEEE 754 decimal64 and decimal128 under 3-clause BSD: http://www.netlib.org/misc/intel/ http://www.netlib.org/misc/intel/
- ghewgill 9y agoAlso see Intel's own page about their decimal floating point library: https://software.intel.com/en-us/articles/intel-decimal-floating-point-math-library/ https://software.intel.com/en-us/articles/intel-decimal-floa... I don't know how much effort Intel is allocating to this project; I sent a bug report to the author listed on that page in 2015. The bug was acknowledged and fixed, with a new release out in "several days", but nothing yet.
- hoosieree 9y agoI imagine this would be useful for applications which do a lot of conversion from/to ieee754 to/from text... Programming languages and spreadsheet software come to mind. Has anyone ported a non-trivial application to use DEC64, and compared the results?
- microcolonel 9y ago> In modern systems, this sort of memory saving is pointless. By giving programmers a choice of number types, programmers are required to waste their time making choices that don’t matter. Even worse, making a bad choice can lead to a loss of accuracy or destructive bugs. This is a bad practice that is very deeply ingrained. Boundless arrogance, minimal information. If you want a decimal floating point type, use the IEEE formats, there are high quality implementations everywhere, and if you're using C++ you can probably switch without much more than a string replacement and a couple header includes. Douglas Crockford can be forgiven for having apparently no concept of computing at the limits of the machine (in terms of cache latency, memory size, and CPU throughput), but if you get comfortable with this level of ignorance and aren't famous, you will be highly replaceable. Added: Moore's law is effectively dead. This means that for a given CPU microarchitecture family and your monetary or spatial budget for memory, you have limited resources to achieve your goals. If you write an inefficient program with no regard for performance at the numerics level, your program will no longer automatically get much faster and cheaper to run, you will instead be contributing to the pile of performance debt your successors will be cursing and shedding tears over. Furthermore, with his "loss of accuracy" comment, he seems to imply that his 64 bit decimal types are even remotely large enough that common users will not lose accuracy (by which I suppose he really means precision).
- ChuckMcM 9y agoA much better discussion and design for decimal arithmetic on binary computers was done by Mike Cowlishaw (http://speleotrove.com/decimal/ http://speleotrove.com/decimal/) He shifted the entire computation chain into decimal (representing decimal digits in a packed form as well)
- olliej 9y agoUgh having an explicit bit prior to the decimal was a mistake intel made in x87 - it introduces a pile of horror as there end up being multiple representations of the vast majority of numbers, which means you have to normalize prior to any comparison operation, or accept the your comparisons may be wrong The explicit leading bit directly halves the space of addressable bits (which is how you get space for multiple representations) If you want insight to how awful this is, x87 has pseudo infinities, pseudo /nans/, unnormal values, and pseudo denormals The solution intel eventually took was to recognize that the leading bit was useless but require it to be as though it were implicit and treat any case where that is wrong as being invalid. So yes you do want a format that requires normalization, because the alternative is one that requires normalization anyway, but is also insane for any kind of comparison, and wastes precision needlessly.
- qwerty456127 9y agoThis ought to be built into everything so financial applications can stop using slow software decimal types.