And in case anyone's wondering about handling it by representing the repeating digits instead, here's the decimal representation of 1/12345 using repeating digits:
0.0[0008100445524503847711624139327663021466180639935196435803969218307006885378
69582827055488051842851356824625354394491697043337383556095585257189145402997164
84406642365330093155123531794248683677602268124746861077359254759011745646010530
57918185500202511138112596192790603483191575536654515998379910895099230457675172
13446739570676387201296071283920615633859862292426083434588902389631429728635074
92912110166059133252328878088294856217091940056703118671526933981368975293641150
26326447954637505062778452814904819765087079789388416362899959497772377480761441
87930336168489266909680032401782098015390846496557310652085864722559740785743215
87687322802754151478331308221952207371405427298501417577966788173349534224382341
02875658161198865937626569461320372620494127176994734710409072498987444309437019
03604698258404212231672742]See also binary coded decimals.
> Programmable calculators manufactured by Texas Instruments, Hewlett-Packard, and others typically employ a floating-point BCD format, typically with two or three digits for the (decimal) exponent.
That is true, but most humans in this world expect 0.1 to be represented exactly but would not require 1/3 to be represented exactly. Because they are used to the quirks of the decimal point (and not of the binary point).
This is a social problem, not a technical one.
https://en.wikipedia.org/wiki/Decimal_floating_point#IEEE_75...
But it's still not much used. E.g. for C++ it was proposed in 2012 for the first time
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n340...
then revised in 2014:
http://open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3871.ht...
...and... silence?
https://www.reddit.com/r/cpp/comments/8d59mr/any_update_on_t...
Seeing the occasional 0.300000000000004 is a good reminder that your 0.3858372895939229 isn't accurate either.
One can argue that nothing is important to most people.
The correct calculations involving money, up to the last cent, are in fact important for people who do them or who are supposed to use them. I've implemented them in the software I've made to preform some financial stuff even in eighties, in spite of all the software which used binary floating point routines. And, of course, from the computer manufacturers, at least IBM cares too:
https://www.ibm.com/support/pages/decimal-floating-point-use...
Apparently, there are even processors which supports these formats in hardware. It's just still not mainstream.
Not really. It would be really cool if fixed point number storage were an option... but I'm not aware of any popular language that provides it as a built-in primitive along with int and float, just as easy to use and choose as floats themselves.
Yes probably every language has libraries somewhere that let you do it where you have to learn a lot of function call names.
But it would be pretty cool to have a language with it built-in, e.g. for base-10 seven digits followed by two decimals:
fixed(7,2) i;
i = 395.25;
i += 0.01;
And obviously supporting any desired base between 2 and 16. Someone please let me know if there is such primitive-level support in any mainstream language!Every programming language that has come since has been designed to be a general purpose programming language, therefore they don't include fixed point as a first class data type.
Therefore the financial industry continues to use COBOL.
Every time someone some tries to rewrite some crusty COBOL thing in the language de jure, they'll inevitably fuck up the rounding somewhere. The financial industry has complicated rounding rules. Or better yet, the reference implementation is buggy and the new version is right, but since the answers are different it's not accepted.
DOOM's implementation of fixed-point is a good example which should work on any platform as long as sizeof(int) >= 4.
https://github.com/id-Software/DOOM/blob/master/linuxdoom-1.... https://github.com/id-Software/DOOM/blob/master/linuxdoom-1....
Addition and subtraction will work normally. Multiplication also works normally except you need to right-shift by FRAC_BITS afterwards (and probably also cast to a larger integer type beforehand to protect against overflow).
Division is somewhat difficult since integer division is not what you want to do. DOOM's solution was to cast to double, perform the division, and then convert that back to fixed-point by multiplying by 1.0 before casting back to integer. This seems like cheating since it's using floating-point as an intermediate type, but it is safe to do because 64-bit floating point can represent all 32-bit integers. As long as you're on a platform with an FPU it's probably also faster than trying to roll your own division implementation.
Fixed point classes have been proposed many times as addition to the standard library, but have yet to be voted in.
[1] see my comment elsethread about trivial problems.
With many operations this trade off makes sense, however its critical to understand the limitations of the model.
Pretty much all languages have some sort of decimal number. Few or none have made it the default because they're ignominiously slower than binary floating-point. To the extent that even languages which have made arbitrary precision integers their default firmly keep to binary floating-point.
You can strike the "none". Perl 6 uses rationals (Rat) by default, someone once told me Haskell does the same, and Groovy uses BigDecimal.
The opposite.
Decimal floating points have been available in COBOL from the 1960s, but seem to have fallen out of favor in recent days. This might be a reason why bankers / financial data remains on ancient COBOL systems.
Fun fact: PowerPC systems still support decimal-floats natively (even the most recent POWER9). I presume IBM is selling many systems that natively need that decimal-float functionality.