Stories
Slash Boxes
Comments

SoylentNews is people

posted by martyb on Monday September 16 2019, @01:48PM   Printer-friendly
from the COBOL-is-often-fractionally-better dept.

https://medium.com/@bellmar/is-cobol-holding-you-hostage-with-math-5498c0eb428b

Face it: nobody likes fractions, not even computers.

When we talk about COBOL the first question on everyone's mind is always Why are we still using it in so many critical places? Banks are still running COBOL, close to 7% of the GDP is dependent on COBOL in the form of payments from the Centers for Medicare & Medicaid Services, The IRS famously still uses COBOL, airlines still use COBOL (Adam Fletcher dropped my favorite fun fact on this topic in his Systems We Love talk: the reservation number on your ticket used to be just a pointer), lots of critical infrastructure both in the private and public sector still runs on COBOL.

Why?

The traditional answer is deeply cynical. Organizations are lazy, incompetent, stupid. They are cheap: unwilling to invest the money needed upfront to rewrite the whole system in something modern. Overall we assume that the reason so much of civil society runs on COBOL is a combination of inertia and shortsightedness. And certainly there is a little truth there. Rewriting a mass of spaghetti code is no small task. It is expensive. It is difficult. And if the existing software seems to be working fine there might be little incentive to invest in the project.

But back when I was working with the IRS the old COBOL developers used to tell me: "We tried to rewrite the code in Java and Java couldn't do the calculations right."

[Ed note: The referenced article is extremely readable and clearly explains the differences between floating-point and fixed-point math, as well as providing an example and explanation that clearly shows the tradeoffs.]


Original Submission

 
This discussion has been archived. No new comments can be posted.
Display Options Threshold/Breakthrough Mark All as Read Mark All as Unread
The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
  • (Score: 3, Insightful) by bradley13 on Monday September 16 2019, @04:01PM (10 children)

    by bradley13 (3053) on Monday September 16 2019, @04:01PM (#894653) Homepage Journal

    On the one hand, there's nothing wrong with the idea of "never touch a running system". Cobol works, and by now the compilers and libraries have been thoroughly proven.

    On the other hand, claiming other programming languages cannot do fixed-point math is dumb. And anyway, that's actually not really the point. TFA seems not emphasize the real point: you should not use binary representations for decimal numbers. They mention programs written for the IRS: If anyone uses floating-point numbers for financial calculations they are screwed before they start. You *must* use decimal arithmetic, which means that you have two solutions:

    There are three clean solutions:

    - Shift your decimals so that you can do integer math, and shift back, for the final result. In other words, implement (or use) a fixed-point library. If Cobol has some oddities in rounding/truncation, you can implement those as needed. This would allow you to use binary integer types, as long as you stay below the maximum values.

    - Use a library that correctly implements decimal arithmetic (like Java's BigDecimal). TFA mentions this, but doesn't really bring the point home. This is the cleaner solution, but may deliver results slightly different from existing Cobol code.

    - If the performance of libraries like BigDecimal is a problem (unlikely, but possible) then implement Cobol-style math in a new library. If Cobol compilers can do it, so can libraries in other languages. The operations are well-understood (um, because the Cobol compilers have already implemented them), so this is entirely possible.

    "We tried to rewrite the code in Java and Java couldn't do the calculations right."

    Color me unimpressed. They apparently weren't very good programmers, or at least they did not understand Java.

    - - - - -

    P.s. For anyone who doubts the inaccuracy of using binary arithmetic for decimal values, consider the following program:

    float A = 1000000;
    float B = (A + 1) / 1000;
    float C = A / 1000;
    float D = B - C;
    float E = 1000000 * D;
    float F = E - 1000;
    System.out.println("F should be 0.0, but is actually " + F);

    Result:

    F should be 0.0, but is actually -23.4375
    --
    Everyone is somebody else's weirdo.
    Starting Score:    1  point
    Moderation   +1  
       Insightful=1, Total=1
    Extra 'Insightful' Modifier   0  
    Karma-Bonus Modifier   +1  

    Total Score:   3  
  • (Score: 2) by FatPhil on Monday September 16 2019, @04:13PM (5 children)

    by FatPhil (863) <pc-soylentNO@SPAMasdf.fi> on Monday September 16 2019, @04:13PM (#894662) Homepage
    Now use decimal, and replace those 1000s with 1001, 1000000s with 1002001s, and report back.

    You see, if you want to do anything apart from multiply and divide by factors of powers of 10, you "are screwed before [you] start".

    No difference from binary. Read some Kahan (or at least /What ever computer scientist should know about floating point arithmetic/) before bloviating so.
    --
    Great minds discuss ideas; average minds discuss events; small minds discuss people; the smallest discuss themselves
    • (Score: 5, Touché) by bradley13 on Monday September 16 2019, @04:36PM (4 children)

      by bradley13 (3053) on Monday September 16 2019, @04:36PM (#894671) Homepage Journal

      The point is this: When you are doing financial calculations, you are using powers of 10. Because that's how currencies work.

      --
      Everyone is somebody else's weirdo.
      • (Score: 4, Insightful) by FatPhil on Monday September 16 2019, @05:58PM (2 children)

        by FatPhil (863) <pc-soylentNO@SPAMasdf.fi> on Monday September 16 2019, @05:58PM (#894729) Homepage
        False. You're thinking of noddy stuff like ledger accounting where the input numbers have been passed a priori through a filter that has simplified them to be trivial, and exactly handlable in decimal. This is only a subset of financial computations. If you can't imagine exponentiation to a non-integer power ever happening in the world of finance, then *put down the calculator, and walk away, you're not safe in charge of such a thing*. Or become president of the USA.
        --
        Great minds discuss ideas; average minds discuss events; small minds discuss people; the smallest discuss themselves
        • (Score: 2) by DannyB on Monday September 16 2019, @06:03PM (1 child)

          by DannyB (5839) Subscriber Badge on Monday September 16 2019, @06:03PM (#894733) Journal

          I have written calculations like you describe in a financial calculation. That calculation is a black box. It takes inputs, does an inexact calculation, to great precision, and then the results are fixed into some form of currency values that are the result(s) of that black box.

          Everyone who does the same calculations (different languages, implementations, etc) will get the same results. But outside that black box, you're back to some kind of currency representation of money.

          Values of money have always been integer data types since before recorded history. The age of computers did not change that.

          --
          People today are educated enough to repeat what they are taught but not to question what they are taught.
          • (Score: 2) by FatPhil on Tuesday September 17 2019, @07:05AM

            by FatPhil (863) <pc-soylentNO@SPAMasdf.fi> on Tuesday September 17 2019, @07:05AM (#895044) Homepage
            > Values of money have always been integer data types since before recorded history.

            I'd change that to "Values of money have always been values representing integer multiples of an atomic unit of value since before recorded history." as we've usually chosen a fixed point representation. If the base unit of currency was the cent, rather than the dollar, then many of the issues people bring up would simply evaporate. This is because decimal-heads love saying stupid things like "you can't represent $0.01 exactly in binary", which is patently false if you're representing cents. If you encounter side effects like "1 dollar (100)" * "1 dollar (100)" = "100 dollars (10,000)", then you are almost certainly doing something wrong, as there's no such thing as a square dollar.

            But you seem to get it - firstly you need an exact representation for every value that you wish to represent (can be fixed point, can be floating point suitably scaled, can be decimal FP, can be integer). Binary FP based on dollars is not such a beast - noone's denying that. Once you've got that, then operate on those values using whatever is most accurate. And given that you want to avoid overflow at all costs, that's almost certainly FP. And as I've mentioned elsewhere, binary provably does better than decimal.

            The problem is when people fail to perform that first decision-making step correctly. Some languages protect idiot programmers against this better than others. I personally think it's better to just not hire idiot programmers, as they'll make a mistake elsewhere.
            --
            Great minds discuss ideas; average minds discuss events; small minds discuss people; the smallest discuss themselves
      • (Score: 3, Informative) by DannyB on Monday September 16 2019, @05:59PM

        by DannyB (5839) Subscriber Badge on Monday September 16 2019, @05:59PM (#894730) Journal

        It is powers of 10 true. But it is also true that currencies are ALWAYS integers. Never approximations like floating point.

        Once you recognize it is integers, you can use integer types for much greater efficiency. Integer arithmetic is always EXACT. Even division has an exact quotient and remainder. EXACT. No fuzzyness, ambiguity or imprecision. All currency values (within range) are exactly representable as integer. Conversion to and from Base 10 for printing and parsing is also EXACT. So for Five Dollars you would use an integer of 500.

        --
        People today are educated enough to repeat what they are taught but not to question what they are taught.
  • (Score: 2) by Dr Spin on Monday September 16 2019, @04:13PM (1 child)

    by Dr Spin (5239) on Monday September 16 2019, @04:13PM (#894663)

    I think 64 bit integers are still large enough to handle the current US debt as cents.

    However, if Trump remains in power, this may not be so for much longer. In which case, you could always use double precision.

    OTOH, if you are using floats for money, you should probably get a head transplant.

    --
    Warning: Opening your mouth may invalidate your brain!
    • (Score: 2) by DannyB on Monday September 16 2019, @04:59PM

      by DannyB (5839) Subscriber Badge on Monday September 16 2019, @04:59PM (#894682) Journal

      64 bit integers can hand the US National Debt as expressed in Argentine Pesos, which is a larger magnitude number.

      As you say, NEVER use floats for money. I thought everyone figured that out in the 1970's. Why in the 21st century does nobody seem to know that.

      --
      People today are educated enough to repeat what they are taught but not to question what they are taught.
  • (Score: 2) by sjames on Monday September 16 2019, @11:04PM

    by sjames (2882) on Monday September 16 2019, @11:04PM (#894868) Journal

    - Use a library that correctly implements decimal arithmetic (like Java's BigDecimal). TFA mentions this, but doesn't really bring the point home. This is the cleaner solution, but may deliver results slightly different from existing Cobol code.

    That could be a big problem during validation (nobody is going to put a program in charge of that much money without some serious validation).

  • (Score: 1) by dumain on Thursday September 19 2019, @08:25AM

    by dumain (8558) on Thursday September 19 2019, @08:25AM (#896017) Homepage

    Guile Scheme has exact rationals as a built in type which should be able to adequately represent both fixed point and BCD. Guile can also be interfaced to GNUCobol so the transition to the smugly superior programming language could be managed in accord with modern buzzwords (Agile!,Devops!).