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
Technically correct, but fails to address the core point that this might be a terrible idea.
Also, it's worth mentioning 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.
1 / 0 == 0 / 0 == (-1) / 0 == MAX_DEC64 + X == (-MAX_DEC64) - X
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.
"nan is equal to itself."
Edit: I see Stormbrew made the point before me, lower down the thread.
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/
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)
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.
- 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.
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.
My main problem with writing it out is code size, since ideally you want every single integer operation in your nice fast C-like-language program to expand to that kind of sequence. But maybe it doesn't actually matter that much.
What you want is called software interrupt or exception. MIPS and Alpha can do it for integer overflows. SPARC can do it for the two bottom tag bits of integers (to distinguish integers from pointers). I bet that if you only wait long enough, you will eventually see an architecture with both features. ;-)
In the meantime we have to fall back to conditional jumps. :-/
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.
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.
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."
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.
As a C programmer, he just seems off his trolley.
The problem is that many extant APIs return 64-bit integers, so if your language only has 56-bit integers you are creating a bug/vulnerability every time you want to talk to the outside world.
e.g. sqlite has sqlite3_column_int64() to get a value from a result set. How do you use that safely if your language can only do 56-bit ints? Ugly.
Remember the "Twitter Apocalypse" when Twitter changed their tweet IDs to be bigger than 56-bits and all the JS programmers had to switch to using strings?
Also, bitboards. Bitboards are cool: https://chessprogramming.wikispaces.com/Bitboards.
EDIT: I also reject the premise that just because there's an ugly hack available, we can get rid of useful language features. Am I working for the language or is the language working for me?
I reject the nanosecond example because it's completely arbitrary. 64 bits of picoseconds would only cover 0.584 years so should we claim 64 bits isn't enough? Wouldn't 2000 years of microseconds in 56 bits be good enough?
I'll give you credit for bitboards though, that's one I hadn't considered.
I have never ever thougt that float/double/decimal was too much choice.
This is proposing a decimal floating point type.
Which is actually not a bad idea. This "specification" is, however, laughable. Especially since there are quite good decimal floating point specification out there that he could have just stolen^H^H^Hborrowed from.
Also, things like converting to/from strings become operations with a priori bounded limits just by taking a quick look at the number of digits if you have decimal floating point.
This is not true for binary floating point. There is a reason why printf libraries are so blasted huge and have malloc issues--it's the binary floating point conversions.
Much of the stupidity we encounter in dealing with floating point (inexact numbers on exact decimals, silly rounding, inability to handle significant figures, weird conversion to/from strings) simply goes away if you use decimal floating point.
In addition, if you go back through the ECMAScript archives, they actually thought about this back in ECMAScript4 but rejected it for some good reasons. I don't agree with those reasons, but they did think about and discuss them.
What is "int truncation" anyway? Overflow?
Sampling modes customize how the value calculation is done. Some will simply round the index to the nearest integer texel, resulting in only one value being accessed (cheap.)
Others will interpolate via weighted average as you're thinking, in the 1D case. Then there's the 2D and 3D cases... plus mipmaps... plus anti-aliasing patterns... at which point you could easily have 16+ samples bearing little resemblance to "indexing an array", especially as one can apply all these interpolation techniques to generic functions such as perlin noise which aren't array based.
Double -> Int
> 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)
> 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.
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.
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?
Binary floating point can accurately represent fractions of the form 1/(2^n). Decimal floating point can accurately represent fractions of the form 1/((2^n)*(5^m)). Either can only approximate fractions with other prime factors in the denominator (1/3, 1/7, 1/11, ...).
In terms of a programmer having to be concerned with accumulated errors due to approximations in the representation, I'd assert that decimal floating point in no way changes the scope of concerns or approach to numeric programming compared to binary floating point. I'd guess even in a domain with a very precise need of fractional decimals, a programmer would still need to reason about and account for numeric representation errors in decimal floating point such as overflow and underflow.
The larger the radix, the more of the mantissa is wasted. Given fixed storage, base 2 floats will have higher precision over their range than higher bases, like 10 and 16.
The difference is easy to illustrate with base 16 and base 2, since we can convert between the two easily. Converting a base 16 float to base 2 will result in leading zeroes some of the time, which could have been used for storing data. The same is true with base 10, but you have to do more math to demonstrate it.
Agree. What problem does this solve? That I can now represent 1/5 precisely?
All the other problems of representing floating point numbers and numbers generally are maintained.
For example, arithmetic operations in binary floating point are notorious for producing mystery meat error quantities, because the actual error quantity is in binary and only later represented as a decimal amount. And when coding it is most natural to account for floating point errors in decimal terms, even though this is a false representation.
So the main thrust of any decimal float proposal comes from "this is more in tune with the way humans think" and not the specific performance and precision constraints.That said, I have no special insights into Crockford's proposal.
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
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.
Basically try to implement a BCD counter in verilog and you'll see where the overhead appears compared to a "dumb" binary counter.
In practice it would be slow because not a whole lot of CPU architectures natively handle BCD. If this "standard" goes mainstream maybe the vendors will adapt and make special purpose "DEC64 FPU" hardware.
I'm not really sure what's the point of using this floating point format outside of banking and probably a few other niche applications. For general purpose computing I see absolutely no benefits.
It would be extremely unintuitive if math could be done faster in any base except for 2 (or a power thereof) when running on a modern CPU.
Have used this for a number of years for financial calculations.
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
Latest draft specification: 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/n284...
Update proposal for C++11: 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
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.
Python's decimal type conforms to IBM's General Decimal Arithmetic Specification  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).
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.
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...
Also, see: http://www.logicalfallacies.info/relevance/fallacists/
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!
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?
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.
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.
As an example with AVX instructions you can process 8 floats at the same time, compared to 4 doubles. So if float is enough for you you can expect double performance in either memory transfer bound or ideally vectorizable algorithms.
And in mobile computer graphics 16bit values are common.
> 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:
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:
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.
> There are also 255 representations of almost all representable numbers. [...] Aside from the fact that you're wasting an entire byte of your representation
How is this different than any other floating-point representation? I'm pretty sure IEEE floating-point has the same redundancy, though numbers are normalized so comparisons are cheaper as you note. But IEEE doubles "waste" even more bits due to the 2^52 representations of NaN.
> For most comparisons [...] it will take around FIFTY INSTRUCTIONS TO CHECK IF TWO NUMBERS ARE EQUAL OR NOT.
Good point, sounds like a notable weakness and barrier to adoption.
> Crockfords bugaboo with IEEE 754 floating-point is bizarre, verging on pathological.
I personally think that the way to handle floating-point confusion is better user education. However, if you really want a decimal standard, then, as I mentioned above, there already is one that is part of the IEEE 754 standard. Not only do there exist hardware implementations, but there are also high-quality software implementations.
A better approach to making things more intuitive in all bases, not just base 10, is using rational numbers. The natural way is to use reduced paris of integers, but this is unfortunately quite prone to overflow. You can improve that by using reduced ratios of – guess what – floating point numbers.
You are not correct. The smallest significand possible is 1x10^1, but you can't delve further into positive exponents. Conversely, 56 signed bits allows the largest integer power of 10 as 10 000 000 000 000 000 so the exponent will be -15. So there are exactly 17 representations of 10, and that's the worst it gets. All other numbers except powers of 10 have fewer representations, and most real world data affected by noise has a single representation because they use the full precision of the significand, and you can't shift them to the right or left without overflow or loss of precision.
So the redundancy is much less than you think, one in 10 real values has two representations, one in 100 has three etc. This is common for other decimal formats and not that big of a problem, detecting zero is a simple NOR gate on all significant bits.
The real problem with this format is the very high price in hardware (changing the exponent requires recomputing the significand) and complete unsuitability for any kind of numerical problem or scientific number crunching. Because designing a floating point format takes numerical scientists and hardware designers, not assembly programmers and language designers.
Heck, the only reason he put the exponent in the lower byte and not the upper byte, where it would have ensured a perfect compatibility to most positive integers, is that X64 assembly does not allow direct access to the upper byte.
Nobody who does anything with numbers believes that! Even if all you can do is count your fingers you believe in the difference between integers and floats. They have different algebraic properties entirely and it takes a whole hell of a lot of work to get from one to the other---there's even a whole class (fractions) in between.
It's confusing because it is very difficult to look at a decimal number and know whether it can be represented exactly as base-2 floating point. It's especially confusing because you get no feedback about it! Here is a Ruby session:
I couldn't find any (like not a single one), so I wrote a program myself to do it: http://blog.reverberate.org/2012/11/dumpfp-tool-to-inspect-f...
If you know of a program in any of these languages that will print this value for "0.1" using built-in functionality, please let me know because I would love to know about it.
Likewise the precise value of double(1e50) is 100000000000000007629769841091887003294964970946560. Anything else is an approximation of its true value.
In another message you said that what's really important is that the string representation uniquely identifies the precise value. While that will help you reconstruct the value later, it does not help you understand why 0.1 + 0.2 != 0.3.
>>> from decimal import Decimal
toRational 0.1 = 3602879701896397 % 36028797018963968
toRational 1e50 = 100000000000000007629769841091887003294964970946560 % 1
rasky at monocle in ~
Python 2.7.5 (default, Sep 2 2013, 05:24:04)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
rasky at monocle in ~
Python 3.3.3 (default, Dec 24 2013, 13:54:32)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.2.79)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
Python 3.3.5rc1 (default, Feb 23 2014, 17:44:29)
>>> 0.3 == 0.2 + 0.1
>>> 0.2 + 0.1
This isn't true. Only zero has 255 representations. All other numbers are limited by the size of the coefficient, 16 digits. So a number with 1 significant digit would have 16 representations, one with two would have 15, etc. Not that I'm defending the format, but if we're critiquing it for being sloppy, we need to be careful about such things.
> For most comparisons (no, comparing numbers with the same exponent is not the norm)
I'd say that exponent 0 is the norm, meaning precise numbers in a really wide range, isn't it?
What I meant by exponent zero not being the norm is that most numbers you work with won't have exponent zero. Specifically only one in 2^16 of the possibly representable values and only one in 2^24 of the possible representations. If you're using the "natural" representation, then only the integers -9 through 9 have zero exponent.
"Because the significand is not normalized, most values with less than 16 significant digits have multiple possible representations; 1×102=0.1×103=0.01×104, etc. Zero has 768 possible representations (1536 if you include both signed zeros)."
This actually had a significant impact on the implementation of IEEE754 on the DEC Alpha chips. The DEC Alpha microprocessors used a software trap whenever a denormal was encountered.
This was a fine idea--until you start emulating an x86 and discover that one of the big programs you want to support--AutoCAD--buries things into denormals and your performance is dog-slow.
Of course ... That's true of any decimal number representation with an exponent. Why is it a problem?
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."
(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
>>> from decimal import Decimal as D
>>> D("10")/D("3") * D("9")/D("4")
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.
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.
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.
...and well-understood numerical behavior...
I have been thinking of running a floating-point school just for this reason. Lots of gotchas.
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.
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.
And we're done here folks.
A: Because DEC 25 = OCT 31
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.
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.
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/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.
In fact, the only line of actual substance in your post is "For example, rounding modes and overflow behavior are not addressed", and it turns out that's only true for the descriptive web page, not the reference implementation.
I'll just quote pg here:
Yeah, we know that. But is that the most interesting thing one can say about this article? Is it not at least a source of ideas for things to investigate further?
The problem with the middlebrow dismissal is that it's a magnet for upvotes. The "U R a fag"s get downvoted and end up at the bottom of the page where they cause little trouble. But this sort of comment rises to the top. Things have now gotten to the stage where I flinch slightly as I click on the "comments" link, bracing myself for the dismissive comment I know will be waiting for me at the top of the page.
From my own understanding, an operation will lose precision iff () the result cannot be represented with 52 significant coefficient bits. Logically, the same happens in IEEE754, the difference is that the loss of precision in DEC64 is always a multiple 3.5 bits, whereas IEEE754 can lose precision in decrements of one bit.
() Maybe excluding over/underflow scenarios.
To clarify, what you say sounds like (I'm pretty sure that's not what you meant) every operation with mixed exponent will lead to loss of precision. From my understanding, that is not the case. It also sounds like every IEEE754 operation with mixed exponents only leads to one bit precision loss while it could lead to much more (in fact to (<total number of fraction bits between the two IEEE754 doubles> - 52).
My gut sense is that this proposal is simply too amateurish to be worth the effort of thoroughly debunking. Floating point is kind of like cryptography: the pitfalls are subtle and the consequences of getting it wrong are severe (rockets crashing, etc). Leave it to the experts. This is not a domain where you want to "roll your own."
He provides a reference implementation. That means this and many other details are defined by code. Quoting dec64.asm: "Rounding is to the nearest value. Ties are rounded away from zero. Integer division is floored."
> Compare the level of thought and detail in this "specification" to ... [Goldberg]
I don't think this comparison is fair. David Goldberg's text is an introduction to the topic. Douglas Crockford describes an idea and gives you a reference implementation.
I dream of a day when we stop thinking of "reference implementations" as proper specifications. The whole concept of a "reference implementation" leads to an entire class of nightmarish problems.
What happens if there is an unintentional bug in the reference implementation that causes valid (but incorrect) output for certain inputs? What if feeding it certain input reliably produces a segfault? Does that mean that other implementations should mimic that behavior? What if a patch is issued to the reference implementation that changes the behavior of certain inputs? Is this the same as issuing an amendment to the specification? Does this mean that other implementations now need to change their behavior as well?
Or, worse, what if there is certain behavior that should be explicitly left undefined in a proper specification? A reference implementation cannot express this concept - by definition, everything is defined based on the output that the reference implementation provides.
Finally, there's the fact that it takes time and effort to produce a proper specification, and this process usually reveals (to the author) complexities about the problem and edge cases that may not become apparent simply by providing a reference implementation.
The spec for a valid transaction in Bitcoin can currently only be defined as "a transaction that bitcoin-qt accepts." The problem is magnified by how disorganized the source code is.
(re: all the web standards that had very wide "interpretation" by different browser efforts, leading to chaos and a whole industry based on fear an uncertainty)
To be fair it is extensively commented, but the comments describe what it does, not why. And for fuck's sake, hundreds of lines of assembly is not a spec, even if it is most readable code in the world
I don't agree with that, and I don't think BASIC has much (if anything) to offer in terms of good language design.
From http://bitsavers.trailing-edge.com/pdf/dartmouth/BASIC_Oct64..., that appears to be the case.
Off topic: in that PDF (page 4) the letter "Oh" is distinguished from the numeral "Zero" by having a diagonal slash through the"Oh". Yes, that program printed "NØ UNIQUE SØLUTIØN".
That made me think of the periodic rants here on HN about the supposedly neigh insurmountable inconsistencies in mathematical notation.
> nan is also the result of operations that produce results that are too large to be represented.
It's a polemic, designed to try and propagate an idea and change minds.
It didn't change my mind much, but I found your comment more affecting - in the humorous!
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.
Decimal floating point is actually a good, underutilized idea. However, there is a VERY good specification here:
It is written by people who understand the problem, and have thought quite deeply about the solutions.
As opposed to this pile of garbage ...