You don't use decimals. You use integers, just as BCD is fundamentally integer, and insert a "." character only when printing.
Then, your abstract decimal data type needs to have a separate field for the base power of ten -- which literally makes it a radix-10 floating point.
No.
Nice of you to not include the next sentence in that paragraph,
"You can obviously have radix-10 fixed point types as well.", so you can say you used radix-10 fixed-point instead; i.e. integer values in units of 10
-n of the base currency unit.
And I'm the one who gets called a troll here. Hmph.
I absolutely did use FP values to represent money in all that software running on 68020+68882 and up to PowerPC. And, rarely, x86.
Explains a lot about the state of our financial system. (Kidding!)
No, of course you can write safe and mathematically correct software using BCD, binary integers, floating-point numbers, or even ASCII decimal strings.
It is the
obvious or
naïve way of using floating-point numbers (not pure integers, but using decimals to represent fractional amounts of the base currency unit) in a financial system that is bad -- because often used values cannot be represented exactly in binary floating point.
Yes, you could even work out how to do all needed operations (including interest calculations) that work mathematically correctly even when you use floating-point numbers the obvious way, although it is nontrivial and slow, and you need to be Kahan sum -level careful when implementing each.
The fundamental problem lies, as usual, completely within us humans: what you mean exactly when you say "use floating-point types", and so on.
Even if you the original developer understand it, you also need to understand the rules by which your compiler works; and anyone modifying or maintaining the code later on must do so too. I like to use the term "maintainability", because it is not just readability; it is about how easy or hard it is to understand the entire logic structure that governs the functioning of the program, and work within it.
For financial software, you don't get to do approximate totals; everything must match to the smallest currency unit recorded. If you use floating point values like you would with normal numerical computation, with fractional parts representing fractional currency units, that won't happen unless your hardware FP is radix-10, because commonly used values cannot be represented exactly. You
can work around it, and brucehoult has outlined some experience on how that has been done by using integers only, in units of the smallest fraction needed, while still technically using FP and FP operations. Another way to do it is via BCD. A yet another way is via pure binary integers. You can even use ASCII strings representing the numerical values -- it's easier than what one might think.
The issue is that just writing the code and claim it does what is asked, is just a small part of software engineering. Sometimes you use an inefficient implementation, because the tradeoff between efficiency and maintainability warrants it. If you need something to be efficient
and reliable, you test the hell out of it, and acknowledge that if it needs to be "modified", it is better rewritten from scratch using the full sets of (changed) requirements, and ensure the requirements defining the operational rules are well documented.
It would be so nice to write code just for myself, and to hell with maintainability -- but then we wouldn't be able to stand on the shoulders of giants; we'd just all be standing out there in the field, reinventing the same wheels again and again.
To circle back at the original topic, this also means that the subset of instructions say GCC uses isn't really indicative of much: it is difficult to tell if the unused subset is unused because GCC is inefficient, or because that subset is just not useful. Similarly for BCD: just because a bunch of programmers cannot immediately see a killer use case for it, does not mean there isn't one.