Hacker News new | ask | show | jobs
by fc_barnes 2524 days ago
My understanding is that part of COBOL's longevity stems from its particular handling of fixed-point math being a specified requirement of various financial contracts. Odd to see this write-up not mention fixed-point math, actually.
5 comments

It's been interesting to observe this impedance mismatch in practice. My first job was writing software for a startup that sold to quant hedge funds. I did a bunch of research on my own, and one of the best practices I ran across was do not use floating point to represent money. Represent everything in terms of integer units of the most basic currency unit (usually cents), to avoid round-off errors. Then I took this information to my CEO, who shot me down on the basis that all their customers used floating point for their internal models, and so I'd be needlessly introducing friction.

And now I'm doing cryptocurrency analytics. The basic unit of Bitcoin is the satoshi, and in the protocol, all transactions are denominated in satoshis. (Similarly, in ethereum, the base unit is the wei and all transactions are denominated as 256-bit words of wei.) And yet basically all exchanges are still using floats. Sometimes they quote them as strings to avoid round-off, sometimes it's double-precision, but internally, it's all just floating point math. So once again I find myself doing everything in terms of floats, even though the underlying financial instrument uses integer units of a very small denomination.

Now that there's a huge proliferation of cryptocurrencies, I wonder if we'll eventually see one that gives up on this point and defines money as IEEE 754 double-precision floating point numbers.

Seems like someone familiar with inflection points in floating point representation could pull an Office Space-style skimming scheme against a floating point based system by perfectly legal means simply by making a lot of transactions of carefully selected sizes.
Interesting idea. Most of the inflection points I've observed have actually been at transaction/analytics boundaries. Transactions are in integer units, analytics are in floating point. It's done this way because many algorithms (including most linear algebra, statistical, and machine-learning algorithms) operate on floats for efficiency, while transactions operate on ints for accuracy.

This isn't directly attackable, but you could potentially trick a trading algorithm into performing stupid trades by feeding it subtly inaccurate data. If you know the particular algorithm used, though, there are probably easier ways to construct adversarial inputs and trade against them. This is why virtually all trading shops keep their algorithms secret, and also slice up & mix their outgoing orders randomly so you can't observe the output of the algorithm.

Floating-point precision can work depending on the financial application. If you are back-testing on exchange data, your simulation code only buys or sells at the bid or ask prices, so even if the signal has floating point imprecision, it doesn't really affect the result. On valuation work, getting the inputs into a DCF/reverse DCF right is much more important than exact precision. I realize this is vastly different than writing an accounting application, but for most hedge funds, it probably won't make a difference to use floats vs. decimals.
> Then I took this information to my CEO, who shot me down on the basis that all their customers used floating point for their internal models, and so I'd be needlessly introducing friction.

Sounds like all there customers had already worked around the bugs and they didn't want to backtrack. Floating point can be horrible because not only do both sides have to use it but they have to process their calculations in the exact same way with the same order, with decimal types you will get consistent results.

Throw in some other complexities like different clients using different value precisions, different currencies having different fractional values (japan has no decimal places, a Kuwait cent is a thousandth of a dollar) combinations of those two and more, then using decimals/money types are just easier.

both COBOL and even RPG both excel at business math and on many systems you can put any face you want on these programs in the back end and just leverage years if not decades of work.

languages without oddities and gotchas do tend to lend themselves to stable systems

(I could google this but I feel like a discussion would be more fun!)

What exactly is fixed point math? The way I deal with currency is to use decimal floating point, ie 'decimal' in C#. Is fixed point simply using integers with and making your base unit cents, not dollars?

In fixed point math, the decimal point (the units digit) is "fixed" at a particular value instead of "floating". A fixed-point number is an integer that represents values as a multiple of 1/N, so fixed-point multiplication requires adding an extra divide-by-N and fixed-point division requires adding an extra multiply-by-N. A floating point number represents numbers as a pair (e, m) such that the result is m * b^e (where b is the base, see below).

Decimal versus binary is orthogonal. A decimal fixed-point number means that N will be a power of 10, and usually clips the range such that there are fixed number of decimal digits available (e.g., between -1,000,000 and +1,000,000). A binary fixed-point number means that N will be a power of 2, and clips its range to fix the number of binary digits (e.g., between -1,048,576 and +1,048,576). Binary floating point means that the base in arithmetic is 2, whereas decimal floating point means that base in the arithmetic is 10. C#'s `decimal` type is a non-standard decimal floating point, which looks to make the mantissa be a binary range instead of a decimal range (i.e., the maximum is not 10^n - 1 for some n).

Could be cents or even mills, but essentially yes.
I'd love to know more about what it does with fixed point math that's considered particular or special. Any links would be greatly appreciated.

Even more curious to me is how COBOL squares as fast if it's stuck using fixed point math.

You're thinking wrong. If your problem domain needs fixed point math (think financial data), then COBOL isn't "stuck" using it. COBOL is privileged to use it, and may well be faster than something that has to use a library to do it.
And it's not like IBM hasn't spent the cash to get decent representations and accelerated hardware over the years.
Why do you say stuck? What do you think is better at handling currency? I can think of integers (multiples of the smaller denomination) or fractions (which are quite slow), definitely not floats.
I agree that fixed point is the way to go for currency. But I read that as meaning COBOL didn't have floating point data types at all. I'm guessing that assumption was wrong. The advantage to floating point math over fixed point is speed. If it wasn't for that, nobody would ever want to use floating point.
No, fixed-point math is typically faster than floating-point math (except if you have many, many more transistors devoted to the floating-point.) The only time floating-point is ever faster than fixed-point in practice is when (1) your points really are floating, so 13 decimal places of precision is fine, but the magnitude of the result ranges over many orders of magnitude (Fourier transform results and calculator apps being good examples); and when (2) the floating-point hardware can't be used for fixed-point calculations and would just sit idle if you didn't find something to run on it.

The main reason people use floating-point math is convenience. It's like dynamic typing: write your real quadratic equation solver with floating-point math and you can use it for everything, whether the values are 6.02e23 or 555e-9, at the expense of having to do extra computation at run-time, just like dynamic typing lets you implement a single hash table type that works for any type of value. But in fixed-point, unless you're using a pretty fancy language, you need to decide on the magnitude range of your values up front. Maybe 3e-6 to 3e5? Use 16.16. Maybe 4e-3 to 1e11? Use 24.8. It's a pain in the bohonkus. But it's faster, more portable (if reproducible results are necessary) and easier to reason about than floating point.

> The advantage to floating point math over fixed point is speed.

AFAIK this is only because modern CPU's have floating point units (https://en.wikipedia.org/wiki/Floating-point_unit), from memory these became common on home PCs around the time of the 486. A lot of early 3D games used fixed point because it was much faster for those that didn't have a co-processor installed.

Whether any of this is applicable to mainframes I don't know.

IBM hardware has supported packed decimal arithmetic for... ever? The z9 hardware onwards includes decimal floating point (IEEEsomethingorother) support[0] (sizeable PDF warning).

[0] http://publibfi.boulder.ibm.com/epubs/pdf/dz9zr011.pdf

Not great for handling Bitcoin transactions. I would highly recommend against using Cobol for any new cryptocurrency projects.
Is it fixed point math or decimal floating point? These are not the same, but fixed point is fairly trivial to reimplement on any platform; there's even an official "embedded C" extension that adds support for it.