In the real world, there are natural numbers, integers, rationals and real numbers.
Computer languages are designed with types that mimic this real-world number stack. Low-level binary implementation details don't leak unless you're overflowing or using bit operations.
What you're really complaining about is the fact that rationals aren't a first-class type in any popular language. With that I agree, it's a shame that corners were cut we three number types instead of four.
No sense in special casing the number 10 when you can have proper rational numbers with almost equal effort.
Every newbie programmer tries to avoid thing about this by using IEEE floats. They discover, usually years later after some anal auditor has come down on them like a ton of bricks for the hundredth time because the dropped low order bits from 1/3 of a cent hit that 1 in a billion case and effected a significant digit, and then it finally dawns that 1 in a billion isn't really 1 in a billion because thousands of such calculations get combined into a single profit and loss figure that is out by 2 cents and chasing that 2 cents for 2 weeks really only to discover it was caused by a computer can't compute, really, really pisses off the auditor, that you realise if aren't thinking about those fractions of a cent as hard as a C programmer focuses on malloc(), they will have gone to whoop whoop in half the code you have written. You will have nightmares about divide signs for the rest of your life. Crockford seems to think Dec64 allows the programmer to avoid thinking about the problem. He is just as wrong as every newbie programmer.
There is only one safe format for currency that accurately reflects this reality, that forces you to accept that you must think about those fractions of a cent. It is the humble integer. You put in it the lowest denomination: cents in the case of the USA. And then when you write total = subtotal / 3 * 4, and you test it, your error stands out like dogs balls, and you fix it.
"Binary number" as used by grandparent really refers to dyadic rationals (https://en.wikipedia.org/wiki/Dyadic_rational), which are a perfectly well-defined dense subset of the rationals. Similarly, "decimal number" is really "terminating decimal expansion" (or whatever you want to call the decimal analogue of dyadic rational), which is again a well-defined dense subset of the rationals. This is a perfectly valid mathematical distinction; the numbers that people work with day-to-day are much more frequently the latter.
There are reals, they do exist. In the "real" world (as poorly defined as that is).
The issue is, fundamentally, what programming languages call "real numbers" are not real numbers. They are an approximation to a subset of the reals. This approximation has holes, and the implementations work to some degree to define regions of applicability, and regions of inapplicability. Usually people get hung up or caught in the various traps (inadvertently) added to the specs for "Reals".
Its generally better to say "floating point numbers" than "Reals" in CS, simply because floating point is that subset of the Reals that we are accustomed to using.
I definitely agree with the comment on rationals. I am a fan of Perl6, Julia and other languages ability to use rationals as first class number types.
Sadly, as with other good ideas that require people alter their code/libraries, I fear this will not catch on due to implicit momentum of existing systems.
From this, it’s fairly non-controvesial to say that only the computable reals exist; these are a tiny (measure-zero) subset of the reals.
If you go further and assume a fundamentally discrete universe (much more controvesial), then all you can really measure are integers.
This could be solved with a rational-style data type, but I consider the fact that real-style data types don't capture that to also be the implementation leaking.
No, they don't. Floats are meant to represent real numbers reasonably accurately.
Real numbers aren't fractions, and the idea of 'rounding' doesn't even apply to reals.
What you want are rational numbers, they solve your use case perfectly.
Floats don't represent rational numbers properly, and they are not meant to.
Javascript programmers don't need a number type designed for accurately computing trig and square roots and representing pi, but they got one anyways.
[1] http://people.sju.edu/~jhodgson/ppl/lisp/lispman.txt [2] https://dspace.mit.edu/handle/1721.1/5600
They are at least in Clojure, which seems quite popular.
Maybe DEC64 is flawed, but can we stop pretending that we like binary-based default systems for any reason other than the barrier to entry it creates for newcomers and visceral feeling of communing with computer internals.
Binary has a place -- in low-level languages. Like assembler. There's nothing wrong with any language providing a non-decimal system as an optional number type.
The system we have in many high-level languages is a frankenstein of a binary system that you usually interact with through decimal representation.
The proposal gets at least one thing right: the languages of the future will have a numeric system default that has less insanity. But it will take the passing of a generation or two of developers.