Search code examples
mainframepl-i

Why comparision doesn't work as I suspect? PL/I


This comparison prints '0'b. Don't understand why... As I know strings are converted automatically to float in PL/I if needed.

put skip list('-2.34e-1'=-2.34e-1);

Solution

  • I have tested this in our environment (Enterprise PL/I V4.5 on z/OS) and found the same behaviour - under certain compile-options.

    Using the option FLOAT(NODFP) (i.e. do not use native support for decimal floating point, I think the option was introduced with Enterprise PL/I V4.4) the following happens:

    • the literal -2.34e-1 is converted to its internal representation as bin float(6), i.e. short binary floating point
    • the literal '-2.34e-1' is compared with a bin float(6) value, so it has to be converted to a bin float as well
    • since -0.234 does not have an exact representation as a binary fraction it seems the compiler converts it to a bin float(54), i.e. an extended binary floating point value, to get maximum precision.
    • So since -0.234 has an infinite number of digits after the decimal point in its binary representation but the two converted values preserve a different number of digits the values do not compare equal.

    Under FLOAT(DFP) (i.e. when using the machines DFP support)

    • the internal representation of the literal -2.34e-1 is an actual decimal floating point and thus exact
    • as is the representation of '-2.34e-1'
    • so under this compile-option both compare equal and the output of your program is '1'b

    So your problem is a combination of the compilers different choice of data-representation and resulting rounding-errors from using binary floating point of different precision.