"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.
POWER7 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.
It 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.
To 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.
I 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.
It's not completely unnecessary and meaningless. In computer graphics, floating point indexing is used to interpolate between texel values during texture look-up.
I don't typically think of it as indexing an array, but it's conceptually similar in some circumstances I suppose. The hardware still eventually has to read values from integer-based addresses, though. As to the details:
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.
Why does anybody listen to Crockford? He wrote a human-readable data format but refused to give it comments. He wrote an obnoxious linter that bans continue;. Now he's proposing to replace integers with decimal floating point type (what happens if someone wants to store a 64-bit integer?).
Still, hardware is inherently base-2. What I'd like to see is hardware assisted adaptive precision predicates and compilers/runtimes that make proper use of modern instructions.
I have never ever thougt that float/double/decimal was too much choice.
As a succinct example, 64-bits is 584 years of nanoseconds. 56-bits is only 2 years of nanoseconds.
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?
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?
The question is, why do APIs return 64-bit values? In general it's not because they need all 64 bits, it's because the 64-bit integer type is convenient for them. This might make Crockford's proposal completely impractical but it doesn't invalidate the argument that led to it.
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.
Wrong. JavaScript has a binary floating point type.
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.
Which is not bad if that floating point type is decimal. All of your integers do what they're supposed to. In addition, things like the standard programming fail of using "i += 0.1;" as a loop iterator actually work when you use decimal floating point.
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.
I do not see any basis for the statement 'very fast performance on integer values', given that simple calculations like substraction and checking of simple equality require many operations in the proposed standard.
This 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/ as a great repository of decimal float info. I hope it will be updated with some discussion of this proposed format.
One 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.
But 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.
Holy 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.
Was this sweeping pronouncement approved by the Central Committee for the Design of Future Programming Languages (CCDFPL), or is Crockford only speaking for himself?
I 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?
So 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?
I 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.
Because division/multiplication by powers of two is a simple bitshift and can be implemented very easily on silicon. Division/multiplication by ten is complicated and needs many more gates and more time.
Because it's easy to do things in base 2 with binary signals (like the kind used in computers). It's unnatural to use base 10 for anything in this domain.
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.
It's not inherently slower, however you have to add extra logic to correctly handle overflows and the like. However given the size of modern floating point units I doubt it's a massive overhead. Basically they would need to convert back and forth between the native zeros and ones of hardware and the decimal representation. And extra logic might mean slower hardware in certain circumstances.
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's not inherently slower. It's a question of economics. How much are people willing to spend to get a CPU to make it be fast? With IEEE 754 math, there's a lot of monetary incentive because a lot of code uses 754. With a new decimal class, there is much less inventive.
Decimal floating point would hardly affect accuracy compared to binary floating point -- with the exception of domains where the inputs and output are strictly human-readable and human-precise constructs (e.g. banking... is there a better term for this?).
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.
> Decimal floating point would hardly affect accuracy compared to binary floating point
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.
The thing that remains most compelling about decimal encodings is in the types of errors seen and how human-comprehensible they are.
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.
Agreed. 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.
A 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
>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."
As 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/02Numer... ("What every computer scientist should know...")
> DEC64 is intended to be the only number type in the next generation of application programming languages.
It'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.
> The BASIC language eliminated much of the complexity of FORTRAN by having a single number type. This simplified the programming model and avoided a class of errors caused by selection of the wrong type. The efficiencies that could have gained from having numerous number types proved to be insignificant.
I don't agree with that, and I don't think BASIC has much (if anything) to offer in terms of good language design.
I tried finding out whether that "having a single number type" actually were true (the microcomputer versions used a percentage sign suffix (I%, J%) to denote integers).
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.
Not all microcomputer versions of BASIC used the percent sign to designate integers. The one I grew up using (Microsoft BASIC on the TRS-80 Color Computer) used only one representation for numbers, floating point (5 byte value, not IEEE 754 based).
> rounding modes and overflow behavior are not addressed
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.
> He provides a reference implementation. That means this and many other details are defined by code.
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.
On the other hand, if you don't have a reference specification you shouldn't declare something standard.
(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)
Bitcoin suffers from this problem. In fact, some people in the community frown upon attempts to make mining software or clients when bitcoin-qt/bitcoind can just be used instead, for the exact reasons you mentioned.
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.
Said reference implementation is written in x86 assembly. 1261 lines, 650 lines sans comments and blanks.
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
And what if the code has a bug? Code is also difficult to analyze. The people who do numerical computing need to prove theorems about what their algorithms produce.
I would hate if this became the only numeric type available in JS (in fact, I don't want it at all), but it's dishonest to quote "specification" as you have and then dismiss it as such, as it doesn't claim to be one, the word doesn't appear a single time in it, and if you go through to the github repo, the readme explicitly refers to the page as a "descriptive web page".
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 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.
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.
This format is suicide from a numerical stability POV. It will lose 3 to 4 bits of precision for an operation with mixed exponents, whereas double will only lose one. Any kind of marginally stable problem, say eigenvalues with poorly conditioned data, will yield crap.
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).
OK. It looks like the proposed representation represents numbers as a signed 56 bit integer times ten to a signed 8-bit number. That does avoid fiddling with BCD, but it's VERY different from usual floating point. Look at the neighborhood of zero. As with usual floating point there's a gap between zero and the smallest nonzero number... but unlike floating point numbers, the next larger nonzero number is twice the smallest nonzero number. The behavior of numerical methods in DEC64 will, I suspect, be quite different from that of floating point. It would be very interesting to know what the difference is, and I'd hope that proponents of it as "the only number type in the next generation of application programming languages" would exercise due diligence in that and other regards.
I completely accept and agree with your criticism of my criticism.
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."
I 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.
"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...
Rightly or wrongly, Crockford is seen as somewhat of a "god" among the JavaScript crowd, due to his "JavaScript: The Good Parts" book and his work on JSON. Within that crowd, he's seen to posses an extremely high amount of authority. So I think that many of them would see this other work as superior based on his involvement alone, without investigating the ideas and proposals themselves any further.
It doesn't logically follow that it is good because an authority has created it. But it definitely gives us an information gain, in the information theory sense.
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.
In 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.
I 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.
Where'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.
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 (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/
But 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). 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.
Which 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.
> 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.
How 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!
"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?
All 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.
> 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.
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.
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.
You'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.
A 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?
"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.
Instead 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.
I 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/... . 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.
I agree that static prediction would be nice. I wonder if the new Intel bounds checking extension can be abused for that.
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.
> Those cases would jump to a previously configured operation table for software helpers.
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. :-/
I've always thought that something like a REPNZ ADCSB/W/D/Q would be very useful for multiprecision math. Add two numbers in memory, propagate carry, and repeat until you get to the end of the number.
I 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.
> 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:
Nothing 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.
That 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.
And 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...
193 comments
[ 79.7 ms ] story [ 312 ms ] threadIBM 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
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.
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.
What is "int truncation" anyway? Overflow?
EDIT: not a javascript specific thing, rather a float one, methinks
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.
As a C programmer, he just seems off his trolley.
I have never ever thougt that float/double/decimal was too much choice.
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.
Why is that so bad? JavaScript did it.
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.
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.
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.
[0] Maybe.
Edit: I see Stormbrew made the point before me, lower down the thread.
> DEC64 is intended to be the only number type in the next generation of application programming languages.
http://speleotrove.com/decimal/decnumber.html
Have used this for a number of years for financial calculations.
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?
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
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.
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.
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.
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.
In the bigger picture what i fell we are generally missing in most programing languages is an EASY way to store and handle fractions.
(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") Decimal('7.50000000000000000000000000')
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."
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/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.
> nan is also the result of operations that produce results that are too large to be represented.
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.
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.
(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)
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.
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
Why? A similar thing is being used by some JavaScript and Lua implementations. It's called NaN boxing.
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 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.
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."
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!
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/
JSON is a subset of javascript which already existed. He just coined the phrases 'json' and wrote it down.
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.
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."
A: Because DEC 25 = OCT 31
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.
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?
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.
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.
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.
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.
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.
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.
Decimal floating point is actually a good, underutilized idea. However, there is a VERY good specification here: 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 ...
- 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. :-/
https://github.com/oguzbilgic/fpd
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.
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:
does not hold true for all integers in JS.Technically correct, but fails to address the core point that this might be a terrible idea.