13 ms·
DEC64: Decimal Floating Point
As described by Douglas himself, DEC64 is a decimal floating point format for the next generation of
application programming languages.
- yincrash 13y agoto view the description html page: http://htmlpreview.github.io/?https://raw.github.com/douglascrockford/DEC64/master/dec64.html http://htmlpreview.github.io/?https://raw.github.com/douglas...
- danparsonson 13y agoOr handily also http://dec64.com http://dec64.com
- petermonsson 13y ago"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." IBM put hardware support for the IEEE 754-2008 Decimal Format in their POWER architecture. The POWER7 clocks 5 GHz. Decimal floating point is only considered slow because Intel and ARM do not have any support for decimal floating point in hardware. Lack of acceptance probably comes from lack of support in standard libraries rather than inefficiency inherent in the standard. Reference: https://en.wikipedia.org/wiki/POWER7 https://en.wikipedia.org/wiki/POWER7
- NkVczPkybiXICG 13y agoPOWER7 has a max clock of 4.25 GHz according to that reference. Anyhow, clock rate in this case is irrelevant. Look at the instruction latencies. I don't have these handy, but I'd bet $50 at at the chance of winning $10 that decimal floating point instructions (at least the divide) are slower than the IEEE754 ones. These chips are also ridiculously expensive, so probably not the best benchmark.
- tel 13y agoIt can provide very fast performance on integer values, eliminating the need for a separate int type and avoiding the terrible errors than can result from int truncation. What! I do not see how making a float fast on integers should ever eliminate the need for an int type. Ints and Real-approximations like Dec64 are simply different things entirely. It's annoying enough that this happens in Javascript.
- ErsatzVerkehr 13y agoIntegers are also exactly represented in the standard floating point formats, so this isn't even a particular advantage of DEC64. What is "int truncation" anyway? Overflow?
- riffraff 13y agoI believe he means the stuff that happens in js like 111111111111111110000 + 1111 = 111111111111111110000; EDIT: not a javascript specific thing, rather a float one, methinks
- chimeracoder 13y agoTo clarify, they are basic floating-point errors from C that happen to be errors for integers as well in Javascript, because Javascript does not support fixed-precision integers.
- austinz 13y agoI know the author despises types, but sometimes types provide valuable semantic information. Like, indexing into an array using a float is completely unnecessary and meaningless.
- jmpeax 13y agoIt's not completely unnecessary and meaningless. In computer graphics, floating point indexing is used to interpolate between texel values during texture look-up.
- tokenrove 13y agoThis would benefit from a better comparison with IEEE 754-2008 decimal64; he dismisses it as being too inefficient but I don't see much other discussion about it, which is too bad since at least it's already implemented in hardware on some platforms. Also, it's worth mentioning http://speleotrove.com/decimal/ http://speleotrove.com/decimal/ as a great repository of decimal float info. I hope it will be updated with some discussion of this proposed format.
- eliteraspberrie 13y agoOne difference is with non-numbers. IEEE 754 defines several infinities (positive, negative) and several NaN values. DEC64 seems to simplify things to a single NaN value. That seems more practical for the average use case.
- fhars 13y agoBut it complicates things by having 255 different zeros which are all equal, and by defining 1 / 0 == 0 / 0 == (-1) / 0 == MAX_DEC64 + X == (-MAX_DEC64) - X (X being the some number large enough to cause overflow) I'd qualify the proposal as a midbrow dismissial of all the real thought that went into the IEEE float standards (I mean, there is no actual substance to his criticism, except "uh, look, it's so bad nobody uses it," which isn't even true, it is in IBM Power7, IBM zSeries, Fujitsu SPARC64, SAP ABAP and gcc). Floating point on a finite precision computer is hard, you can't gloss over the details and assume you have solved everything by that.
- Karellen 13y agoHoly crap. I was about to comment that NANs are not equal to each other, as is the case in every other floating-point representation on the planet[0]. I wasn't actually expecting the page to say either way, but I decided to have a quick look in the vague hope of finding a quote to support that, and instead discovered: "nan is equal to itself." That strikes me as being very odd, and will likely catch a lot of programmers out who are expecting the "normal" behaviour there. I predict many bugs, and much wailing and gnashing of teeth, as a result. [0] Maybe. Edit: I see Stormbrew made the point before me, lower down the thread.
- jonny_eh 13y agoIs this intended to be used in a future version of JavaScript?
- ErsatzVerkehr 13y agoWorse: > DEC64 is intended to be the only number type in the next generation of application programming languages.
- deleted 13y ago[deleted]
- bananas 13y agoIBM also have a library called decNumber which has decent high level functions as well as 32/64/128 bit types. http://speleotrove.com/decimal/decnumber.html http://speleotrove.com/decimal/decnumber.html Have used this for a number of years for financial calculations.
- joaomsa 13y agoI thought the advantage of 2's complement was that we only had one zero and no additional conversions to do arithmetic on negatives, simplifying operations and ALU implementations. Without normalization, how would that work with DEC64? Set both numbers to the highest exponent?
- haberman 13y agoSo is this primarily a performance vs. convenience thing? If both base2 and base10 floating point are implemented in hardware, what makes base10 inherently less efficient? Also, I don't have a good intuition for the difference in what numbers can be exactly represented. I'd love to see this represented visually somehow. Double precision can exactly represent integers up to 2^53, then half of integers between 2^53 and 2^54, then a quarter of integers between 2^54 and 2^55, etc. Dec64 would be able to exactly represent integers up to 2^55, then 1/10th of all integers between 2^55 and 10(2^55), then 1/100th of all integers between 10(2^55) and 100(2^55). So the "holes" are different, so-to-speak. How would this affect accuracy of complicated expressions?
- NkVczPkybiXICG 13y agoDecimal floating point would almost definitely be slower than IEEE754 if implemented in hardware.
- haberman 13y agoBut why? That is the question I was looking to understand. Why is it inherently slower?
- tomp 13y agoI imagine it's because binary exponents correspond very well to binary arithmetics, while decimal exponents don't. Imagine you have a floating point format which has 8-bit mantissa (i.e. 8 bits to store the digits, without the floating point). You're trying to calculate 200 + 200. In binary, that's 0b11001000 + 0b11001000 = 0b110010000 However, to represent the result you would need 9 bits, which you don't have, so you instead represent it as 400 = 200 * 2 = 0b11001000 * 2 ^ 1. Notice how the resulting mantissa is just the result (0b110010000) shifted one bit. If your exponent is decimal exponent, you would instead have to represent 400 as 400 = 40 * 10 = 0b101000 * 10 ^ 1. In this case, the resulting mantissa has to be calculated separately (using more expensive operations), as it has no connection to the mathematical result of the operation.
- 13y ago
- callesgg 13y agoWhile i find the binary incomparability with with decimals somewhat annoying. In the bigger picture what i fell we are generally missing in most programing languages is an EASY way to store and handle fractions.
- psquid 13y agoAgreed. Both Haskell and much of the Lisp family support rational numbers, the latter with them automatically being used instead of imprecise results when doing divisions which can't be represented accurately. I miss them a lot when working in other languages.
- ErsatzVerkehr 13y agoJust curious, what is your use-case in which you need better support for fractions?
- callesgg 13y agoA simple example: (i will use decimal instead of binary as it is easier and binary suffers from the same stuff but for other numbers) (10/3)x(9/4) == 7.5 but due to the fact that computers store the value instead of the fraction it would come out as something like 7.4999999999 cause instead of doing (10x9)/(3x4) it would do 3.3333333333333 x 2.25
- giovannibajo1 13y agoThis looks like a case for decimal floating point, not fractionals. In Python: >>> from decimal import Decimal as D >>> D("10")/D("3") * D("9")/D("4") Decimal('7.50000000000000000000000000')
- mistercow 13y ago>In the bigger picture what i fell we are generally missing in most programing languages is an EASY way to store and handle fractions. I'm squeamish about that. I fear that a lot of new programmers would overuse a fraction type if it were built in, and this can quickly lead to really poor performance. In most cases, floating point works just fine. Reducing fractions is slow, so you really only want to use them when perfect precision is absolutely necessary. What I see happening is someone new to programming hits a point where they need a fractional number type. They look in the documentation and they see "integer, floating point, fraction" and they say "Aha! Fraction! I know what those are."
- ErsatzVerkehr 13y agoAs a "specification" this document is laughable. For example, rounding modes and overflow behavior are not addressed. The comment that object pointers can be stuffed into the coefficient field (usually called 'mantissa') is completely non-sequitur. Frankly I am surprised to see such a big name behind it. I imagine this project is inspired by the sad state of numerical computing in Javascript, but this proposal will surely only make it worse. The world certainly doesn't need a new, incompatible, poorly-thought-out floating point format. Compare the level of thought and detail in this "specification" to the level of thought and detail in this famous summary overview of floating point issues: https://ece.uwaterloo.ca/~dwharder/NumericalAnalysis/02Numerics/Double/paper.pdf https://ece.uwaterloo.ca/~dwharder/NumericalAnalysis/02Numer... ("What every computer scientist should know...") > DEC64 is intended to be the only number type in the next generation of application programming languages. Jesus, I certainly hope not.
- norswap 13y agoAt the least, overflow is addressed: > nan is also the result of operations that produce results that are too large to be represented.
- GyrosOfWar 13y agoIt's addressed, but in the wrong way. IEEE 754 has positive and negative infinity for a reason. Why do there have to be 255 zero values? Also, what about rounding modes? Floating point math is really, really hard and this specification makes it look too easy.
- kzrdude 13y agoThey want to allow fast "addition with equal exponents" in a single cycle and that requires a zero value for each possible exponent.
- GyrosOfWar 13y agoI see, that makes sense.
- norswap 13y agoFor those who didn't notice, this is an initiative of Douglas Crockford, the inventor of JSON (among other things).
- r0muald 13y agohttp://www.logicalfallacies.info/relevance/appeals/appeal-to-authority/ http://www.logicalfallacies.info/relevance/appeals/appeal-to...
- deleted 13y ago[deleted]
- tel 13y agoHa—I think it's relevant information because it tells me to discount his ideas about numeric types in programming. An Appeal to Lack of Authority.
- JoshTriplett 13y agoI don't think this is necessarily an appeal to authority, for two reasons. First, because some people will treat that authorship credit as a warning label rather than authority; that would make it ad hominem, not appeal to authority. Second, because it actually gives useful context to some parts of this spec: "Oh, it makes sense that the author of a language without integer types would propose a spec that claims you don't need integer types". That's not a logical fallacy at all; that's perfectly reasonable reasoning.
- nicky0 13y agoI read it as a simple statement of fact. Not an argument for or against anything.
- silvertab 13y ago"An appeal to authority is an argument from the fact that a person judged to be an authority affirms a proposition to the claim that the proposition is true." I don't think the person you replied to was claiming that DEC64 was good or bad because it was written by Crockford? Didn't feel like he was passing any judgement, merely pointing out who the author was...
- wglb 13y agoDoes look interesting. However, one nit in terms of interesting architecture: The Burroughs 5000 series had a floating point format in which an exponent of zero allowed the mantissa to be treated as an ordinary integer. In fact, the whole addressing scheme was decimal. The addresses were stored in one decimal digit per nibble, so it was doing decimal at the hardware level. While this looks interesting at first blush, good luck with DEC64 is intended to be the only number type in the next generation of application programming languages. I think float will be around for a while, what with the blinding speed in today's processors, and the availability of 80 bit intermediate precision.
- ErsatzVerkehr 13y ago> I think float will be around for a while, what with the blinding speed in today's processors, and the availability of 80 bit intermediate precision. ...and well-understood numerical behavior...
- aidenn0 13y agoIn my experience float is well understood by very few of those who use it. I have had to explain multiple times to people who have been using floats for years that just because floats have guaranteed minimum 6 significant digits doesn't mean that the result of your calculations will be correct to 6 significant digits.
- wglb 13y agoYes. I have been thinking of running a floating-point school just for this reason. Lots of gotchas.
- sixbrx 13y agoI seem to remember that "wobble" which is how the relative roundoff error relates to the absolute error, becomes worse as the base becomes larger (the ratio being the base itself). So that may be one disadvantage in using a decimal base.
- NkVczPkybiXICG 13y agoWhere's exp(), log(), sin(), cos()? He did the bare minimum amount of work and left all the interesting functionality out. We have relatively fast ways of dealing with these in IEEE754, but I see no equivalent here. I really don't want to rehash the arguments that applied 30 years ago, as they do today. Decimal floating point is good for some things, but to be considered the "only number type in the next generation of programming languages" is laughable.
- tomp 13y agoCast to IEEE754 binary floating point number, perform exp()/sin/..., and cast back. In any case, I don't think DEC64 is intended for those users that need to use cos() et al.
- ErsatzVerkehr 13y ago> In any case, I don't think DEC64 is intended for those users that need to use cos() et al He apparently has other ideas: "DEC64 is intended to be the only number type in the next generation of application programming languages."
- NkVczPkybiXICG 13y agoCasting back and forth is extremely slow. He has a loop with multiplication by 10 inside it in dec_new.
- SimHacker 13y agoQ: Why do programmers confuse Christmas and Halloween? A: Because DEC 25 = OCT 31
- ChuckMcM 13y agoInteresting approach, rather than normalize to 1 it normalizes to the largest whole number. The positives of this are that you don't run into issues with encoding things like .1 that you do in binary (or any repeating binary fraction), the downside is that you lose precision when you have more than 16 digits of precision. And the of course the complaint most folks will throw at it is that it fails differently depending on what 'end' of the number you're losing precision. The largest decimal number you can represent in 56 bits is 72,057,594,927,935 so the largest decimal number you can represent will any digit value is 9,999,999,999,999 (16 digits), and you have "extra" space at the top (0-6). However, to Doug Crockfords credit, the number space it covers is pretty useful for a lot of different things and in scripted languages and other uses that aren't safety related I can see the advantage of an 'fractional integer' type. Edit: Mike Cowlishaw, who is also quite interested in decimal arithmetic has a much deeper treatment here: http://speleotrove.com/decimal/ http://speleotrove.com/decimal/
- spc476 13y agoBut it can still bite you. I got hit with an IEEE 754 implementation detail that took me two days to figure out (http://boston.conman.org/2014/03/05.1 http://boston.conman.org/2014/03/05.1). The same problem would exist with this proposal as well. The summary: RLIM_INFINITY on a 32-bit system can be safely stored in a double. RLIM_INFINITY on a 64-bit system can't. I had code in Lua (which uses doubles as the only numeric type) that worked fine on 32-bit systems, but not 64-bit systems. It took me two days to track the root cause down. (Edit: added summary)
- justincormack 13y agoWhich is why Lua 5.3 will have a 64 bit integer type, and will move away from float types only. You can't interop with external stuff without full 64 bit ints.
- pascal_cuoq 13y ago> Interesting approach, rather than normalize to 1 it normalizes to the largest whole number. The positives of this are that you don't run into issues with encoding things like .1 that you do in binary Nonsense. Binary floating-point too normalizes to the largest possible significand. It then omits the leading 1 from the representation, since the leading 1 is by definition a 1. That this trick is simple to pull in binary is only one of the advantages of a base-2 floating-point representation. The fact that 0.1 is not representable in binary has nothing to do with the choice of representing it as 0x1999999999999a * 2^-56, because it already is, and that does not make it representable.
- pkill17 13y agoHow does he explain storing simple integers in a reasonable amount of space? Any decent programmer will avoid using too many bits for a variable that never exceeds a certain value (short, int, etc). It seems rather foolish and arrogant to claim this one half-implemented number type can satisfy everyone's needs in every programming language. Next week he'll have a number format with 48 mantissa bits, 8 exponent bits and 8 unsigned base bits to define a base value between 0 and 255. Look at all the performance and simplicity involved!
- guard-of-terra 13y ago"Any decent programmer will avoid using too many bits for a variable that never exceeds a certain value (short, int, etc)." Why? Why aren't you use half-bytes also? If all your pointers are 64-bit aligned, all your variables are 64-bit aligned and your processor isn't any faster processing 16-bit numbers - if it even have instructions to process those - than 64-bit numbers?
- ambrop7 13y agoAll your variables are not 64-bit aligned. An array of 16-bit integers will generally use 16 bits (2 bytes) per integer. So will two or more subsequent integers in a struct. In general, variables smaller than the alignment of the CPU (but still power of two sizes) only need to be aligned to their own size.
- userbinator 13y ago> If all your pointers are 64-bit aligned, all your variables are 64-bit aligned and your processor isn't any faster processing 16-bit numbers - if it even have instructions to process those - than 64-bit numbers Memory bandwidth. If the processor can read a single 64-bit integer in a clock cycle, it can read 4 16-bit ones just as well. Memory is slower than the core.
- aidenn0 13y ago> Why? Why aren't you use half-bytes also? I actually use half-bytes when it makes sense; my language of choice has bit-vectors so I can use exactly the number of bits I desire. > If all your pointers are 64-bit aligned, all your variables are 64-bit aligned and your processor isn't any faster processing 16-bit numbers - if it even have instructions to process those - than 64-bit numbers? Maybe I have an array with at least 4 16-bit numbers? If I'm counting bits, then it already means I have a lot of numbers. If I have 2 billion numbers in the range [0,15] Then I can easily represent them in an array of 4 or 8 bit values, but will run into performance issues trying to do so (if I can at all) using a similar array of 64 bit values.
- jcalvinowens 13y ago> DEC64 is intended to be the only number type in the next generation of application programming languages. Is he seriously arguing that integer types should be eliminated? What the hell? I really hope for the author's sake this is a joke.
- NkVczPkybiXICG 13y agoHe's the creator of Javascript, so obviously it is.
- rspeer 13y agoYou've got the wrong person or you're being really subtly tongue-in-cheek. Douglas Crockford is the standardizer of JSON and author of "JavaScript: The Good Parts", in which he popularized non-terrible Javascript. Brendan Eich is the creator of Javascript.
- stormbrew 13y agoA specific thing I haven't seen anyone mention is that NaN is equal to NaN in this, which is quite different from IEEE FP. Although it's a thing that often seems counterintuitive at first glance, doesn't this kind of ruin the error-taint quality of NaN?
- ErsatzVerkehr 13y agoAlso, he defines 0*NaN=0, but 0+NaN=NaN.
- p0nce 13y agoSo that you can divide by 0, get a NaN, then multiply by 0 to make it disappear!
- al2o3cr 13y ago"DEC64 is intended to be the only number type in the next generation of application programming languages." FFS, just because the designers of JS couldn't numerically compute their way out of a paper bag doesn't mean that FUTURE languages should be saddled with that mistake.
- bsder 13y agoCan we please make fun of this "specification" very very loudly as a warning to people who might think this is even a remotely good idea? Decimal floating point is actually a good, underutilized idea. However, there is a VERY good specification here: http://speleotrove.com/decimal/dbspec.html http://speleotrove.com/decimal/dbspec.html It is written by people who understand the problem, and have thought quite deeply about the solutions. As opposed to this pile of garbage ...
- comex 13y agoInstead of being stuck with yet another inaccurate number type for integers, I want to see hardware assisted bigints. Something like: - A value is either a 63 bit signed integer or a pointer to external storage, using one bit to tell which. - One instruction to take two operands, test if either is a pointer, do arithmetic, and test for overflow. Those cases would jump to a previously configured operation table for software helpers. - A bit to distinguish bigint from trap-on-overflow, which would differ only in what the software helper does. - Separate branch predictor for this and normal branches? I don't know much about CPUs, but this doesn't seem unreasonable, and it could eliminate classes of software errors.
- pascal_cuoq 13y agoI see no need to provide a single instruction for this. It can already be implemented in a couple of instructions in standard instruction sets (I am familiar with OCaml's Zarith, which does exactly this: https://forge.ocamlcore.org/scm/viewvc.php/*checkout*/trunk/caml_z_x86_64.S?revision=78&root=zarith https://forge.ocamlcore.org/scm/viewvc.php/*checkout*/trunk/... . Other implementations surely exist). The only inefficient aspect of the current implementation is that most operations contain two or three conditional jumps, two for the arguments and sometimes one for the possibility of overflow. The way modern, heavily-pipelined processors are designed, any instruction that could possibly need to obtain an address from an address and jump to there would have to be micro-coded. Also, from the instruction dependency point of view, the way modern, heavily-pipelined processors are designed, all instructions dependencies are fetched as early as possible (before the instruction is executing and it is known which may be ignored). This is why cmov is sometimes worse than a conditional branch. The entries of the “previously configured operation table” would need to be fetched all the time. Again, the simplest way not to fetch them all the time would be to micro-code the instruction, meaning that it would take about as much time as a short sequence of instructions that expands to the same micro-instructions. There used to be a way in IA-32/x86_64 to annotate conditional branch instructions with a static prediction (cs: and ds: prefixes), which could be useful regardless of the approach, but nowadays I believe this annotation is ignored altogether.
- comex 13y ago
- obilgic 13y agoHere is the fixed point decimal implementation for Golang https://github.com/oguzbilgic/fpd https://github.com/oguzbilgic/fpd
- matmann2001 13y agoI see a few flaws that would prevent this from being a decent hardware type: 1) The exponent bits should be the higher order bits. Otherwise, this type breaks compatibility with existing comparator circuitry. 2) This representation uses 10 as the exponent base. That will require quite a bit of extra circuitry, as opposed to what would be required if a base of 2 was used. Citing examples from COBOL and BASIC as reasons for using base 10 is not a very convincing. 3) With both fields being 2's compliment, you're wasting a bit, just to indicate sign. The IEEE single precision floating point standard cleverly avoids this by implicitly subtracting 127 from the exponent value. 4) 255 possible representations of zero? Wat? 5) This type may be suitable for large numbers, but there's no fraction support. In a lot of work that would require doing math on the large numbers that this "standard" affords, those large numbers are involved in division operations, and there's no type for the results of such an operation to cast into. 6) This data type seems to be designed to make efficient by-hand (and perhaps by-software) translation into a human-readable string. But who cares? That's not a reason to choose a data type, especially not a "scientific" one. You choose data types to represent the range of data you have in a format that makes for efficient calculation and conversion with the mathematical or logical operations you want to be able to perform.
- deathanatos 13y ago> DEC64 is intended to be the only number type in the next generation of application programming languages. Please no. There's a very solid case for integers in programming languages: many places in code call for a number which must be an integer: having the type enforce this is nice: you don't need to check and abort (or floor, or whatever) if someone passes you a non-integer. Basically, anything that does an array index, which is any for loop walking through a memory buffer (which might be an array, a string, a file, the list goes on and on. Anything that can be counted) wants an integer. x[i] where i is not an integer just doesn't make sense: ideally, let a type system enforce that. Granted, of course, that many languages will just truncate a float in an integers context, and so funny stuff does happen (I don't really feel that this is a good thing). (Although interestingly, JS is not one of them.) Personally, I think JS needs an integer type. Especially when you see people start getting into bignum stuff in JS, it gets silly fast, as first you can only store so many bits before floating point loses precision, but even then, even if you have an "integer", JS will find funny ways to shoot you in the foot. For example: x | 0 === x does not hold true for all integers in JS.
- tdicola 13y agoNothing is stopping you from building a natural number/integer on top of a dec64 type. You could add whatever logic necessary like truncating fractional values, throwing exceptions, etc.
- MaulingMonkey 13y agoThat sounds like a lot of work and a lot of pain (and likely bugs) just to end up not quite back at square one thanks to the resulting performance drop. I feel what you've done here is the rough equivalent of pointing out that "nothing is stopping you" from building a webpage generator in brainfuck. It's turning complete after all! You could add whatever logic is necessary, like UTF8, XML, and Json parsing, etc. Technically correct, but fails to address the core point that this might be a terrible idea.
- userbinator 13y agoAnd there's also the fact that 64 bits is overkill for many applications as well - especially when you need to store large arrays of them. Another one of the most difficult to understand concepts for JS-only programmers seems to be the finiteness of memory...
- tdicola 13y agoI think this is pretty interesting and appreciate that it's presented with working code. I think people freaking out that they're taking our precious integers away are being a little brash. A natural number type could easily be built on top of a dec64 type for those cases where you really need only whole numbers.
- NAFV_P 13y agoThe term "mantissa" is related to common logarithms, why is it used in relation to floats?
- jimktrains2 13y agoMantissa is also used as the number being multiplied by a base to a power on calculators. That's basically what it is in floats.
- NAFV_P 13y agoI use the term "significand", because the mantissa is logarithmic, the significand isn't.
- AxeFights 13y agoFrom the blog post > DEC64 is a number type. It can precisely represent decimal fractions with 16 decimal places, which makes it well suited to all applications that are concerned with money. From the reference code > Rounding is to the nearest value. Ties are rounded away from zero. Useful wikipedia entry regarding rounding (http://en.wikipedia.org/wiki/Rounding#Round_half_to_even http://en.wikipedia.org/wiki/Rounding#Round_half_to_even) > This variant of the round-to-nearest method is also called unbiased rounding, convergent rounding, statistician's rounding, Dutch rounding, Gaussian rounding, odd-even rounding, bankers' rounding, broken rounding, or DDR rounding and is widely used in bookkeeping. This is the default rounding mode used in IEEE 754 computing functions and operators. Rounding towards zero isn't compatible with financial calculations (unless you're performing office space style bank theft), so this should never be used for numeric calculations involving money. I wonder what he was really trying to solve with this since he missed a fairly important aspect of the big picture. That being said, there's no problem statement on his entire website to address what actual problem he was trying to solve, so all we see is a half baked solution for some unknown problem. On the plus side, at least he didn't use the "for Good, not Evil" clause in the license this time. edit: formatting
- kevinpet 13y agoThe superman penny shaving attack is not related to rounding behavior. You may multiply with fractional values, but when you add or subtract from a ledger, you are doing so in fixed precision (usually cents). If you were calculating something like interest and consistently rounding in one direction, you'd be either over or undercharging people, but the money wouldn't vanish. In other cases, you need to actually think about rounding mode (e.g. how many shares of AAPL can I buy with $5000). > there's no problem statement on his entire website to address what actual problem he was trying to solve This is very true. I don't understand what problem this is trying to solve, because I don't spend a lot of time confused by the internal detail that a double is binary. The storage format isn't important beyond knowing roughly how many digits of accuracy I can count on.
- StefanKarpinski 13y agoThis is some serious amateur hour. The most glaring problem is this: > There are 255 possible representations of zero. They are all considered to be equal. There are also 255 representations of almost all representable numbers. For example, 10 is 1 x 10^1 or 10 x 10^0 – or any one of 253 other representations. Aside from the fact that you're wasting an entire byte of your representation, this means that you can't check for equality by comparing bits. Take a look at the the assembly implementation of equality checking: https://github.com/douglascrockford/DEC64/blob/master/dec64.asm#L1068-L1105 https://github.com/douglascrockford/DEC64/blob/master/dec64.... The "fast path" (which is ten instruction) applies only if the two numbers have the same exponent. The slow path calls subtraction and returns true if the result is zero. The implementation of subtraction falls back on yet another function, which jumps around even more: https://github.com/douglascrockford/DEC64/blob/master/dec64.asm#L631-L664 https://github.com/douglascrockford/DEC64/blob/master/dec64.... For most comparisons (no, comparing numbers with the same exponent is not the norm) it will take around FIFTY INSTRUCTIONS TO CHECK IF TWO NUMBERS ARE EQUAL OR NOT. Many of these instructions are branches – and inherently unpredictable ones at that, which means that pipeline stalls will be normal. All told, I would expect equality comparison to typically take around 100 cycles. It's not even clear to me that this implementation is correct because at the end of the subtraction, it compares the result to the zero word, which is only one of the 255 possible representations of zero. The lack of a single canonical representation of any number is just as bad for other arithmetic operations and comparisons, if not worse. Crockfords bugaboo with IEEE 754 floating-point is bizarre, verging on pathological. He devoted a section in his book "JavaScript: The Good Parts" to a rather ill-informed rant against it. When I saw him give a talk, I took the opportunity to ask him what he thought would be a good alternative to using IEEE 754. His answer was – I shit you not – "I don't know". Apparently this proposal is the answer. No thanks, I will stick with the amazingly successful, ubiquitous, thoroughly thought out standard, that was spearheaded by William Kahan – one of the greatest numerical analysts of all time. Anyone who doesn't appreciate how good we have it with IEEE 754 should really read "An Interview with the Old Man of Floating-Point" [1], in which Kahan relates just how messed up this stuff was before the IEEE 754 standardization process. It should also be noted that there already is an IEEE standard for decimal floating-point [2], which is not only infinitely better thought out than this drivel, but also is already implemented in hardware on many systems sold by IBM and others, specifically for financial applications. [1] http://www.cs.berkeley.edu/~wkahan/ieee754status/754story.html http://www.cs.berkeley.edu/~wkahan/ieee754status/754story.ht... [2] http://en.wikipedia.org/wiki/Decimal64_floating-point_format http://en.wikipedia.org/wiki/Decimal64_floating-point_format
- deleted 13y ago[deleted]
- awalton 13y ago> There are 255 possible representations of zero. They are all considered to be equal. And we're done here folks.
- sprash 13y agoA real alternative to floating points would be a Logarithmic number system (http://en.wikipedia.org/wiki/Logarithmic_number_system http://en.wikipedia.org/wiki/Logarithmic_number_system) which has been shown to be a "more accurate alternative to floating-point, with improved speed."
- 0x09 13y ago> 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. The C and C++ standards committees have been drafting decimal support based on IEC 60559:2011 (previously IEEE 754-2008) since its creation. Original C TR: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1312.pdf http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1312.pdf Latest draft specification: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1781.pdf http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1781.pdf Original C++ TR: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2849.pdf http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n284... Update proposal for C++11: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3407.html http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n340... GCC, ICC, IBM C, and HP C have adopted the extension. Links to the respective software implementations can be found under "cost of implementation" in the C++11 proposal above, except GCC, which uses IBM's library. Its support is documented here: http://gcc.gnu.org/onlinedocs/gcc/Decimal-Float.html http://gcc.gnu.org/onlinedocs/gcc/Decimal-Float.html Meanwhile, hardware support so far exists in POWER6 and 7 and SPARC64 X. This may seem like slow adoption if you aren't accustomed to the glacial pace of standards processes. Especially in the context of a component as critical as floating point numerics. If there is any holdup it would be lack of demand for this format, which the article's proposal doesn't affect.
- todd8 13y agoPython has three basic numeric types, unbounded integers, floats (with the precision of C doubles), and complex (for example, 5+0.3j). However, its standard library includes both a decimal type and a fraction type. The decimal type has been in the language for over 9 years. The documentation is quite clear [1]. Python's decimal type conforms to IBM's General Decimal Arithmetic Specification [2] which is based on IEEE 754 and IEEE 854. Python's decimal type is very complete. For example Python supports the complete range of rounding options found in these specifications (ROUND_CEILING, ROUND_DOWN, ROUND_FLOOR, ROUND_HALF_DOWN, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_UP, and ROUND_05UP). By comparison Dec64 supports only one. Despite having used Python on and off for over 10 years, I've never felt a need to use this decimal type. Integers and floats seem to work for me (although it's nice to have a good decimal implementation available if I need it). [1] http://docs.python.org/3.4/library/decimal.html http://docs.python.org/3.4/library/decimal.html [2] http://speleotrove.com/decimal/decarith.html http://speleotrove.com/decimal/decarith.html
- microcolonel 13y ago“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.” This is like saying that the sharp blades on scissors (diverse numeric types) make them prone to causing bodily harm to surrounding people(errors due to constraints of types), then concluding that we should replace all scissors (numeric types) with those rounded plastic scissors(dec64 play dough floats) which come with a play dough set. Every time somebody has the idea that by deluding developers more we can save them trouble and make them feel safer, we pat that person on the back and follow their recipe. Then two years later there's a HN post about why you really shouldn't be doing whatever was prescribed.
- joelpetracci 13y agoThe name is a bit confusing. I have seen dec32 and dec64 numbers in some mil std ICDs. I can't find any of the documents online but here [1] is a discussion about dec 32 that links to a pdf which briefly describes the dec32 and dec64 formats. [1] http://stackoverflow.com/questions/1797806/parsing-a-hex-formated-dec-32-bit-single-precision-floating-point-value-in-pytho http://stackoverflow.com/questions/1797806/parsing-a-hex-for...
- anaphor 13y ago>By giving programmers a choice of number types, programmers are required to waste their time making choices that don’t matter So I guess making sure that you can never do array[0.5] before your program ever runs doesn't matter? At least not to Crockford apparently, who seems to have some kind of irrational hatred for static type systems.