Rational Developer for System z
Enterprise PL/I for z/OS, Version 3.8, Migration Guide

IBM1099: mixed FIXED

When compiling some of your code, you may see messages such as:

  IBM1099I W  FIXED DEC(7,2) operand will be converted to FIXED
              BIN(25,7). Significant digits may be lost.

The attributes in your messages may vary, but a sample piece of code that would produce exactly this message is:

  DCL
     1 REC_OUT,
        03  AVAIL        FIXED BIN(31),
        03  TOTAL_SPARE  FIXED DECIMAL(7,2),
        03  WORK_TOTAL   FIXED DECIMAL(7,2);

   AVAIL = 17;
   WORK_TOTAL = 12.2;

   TOTAL_SPARE = AVAIL + WORK_TOTAL;

The new and old compilers implement the final assignment in exactly the same way and both would leave TOTAL_SPARE with the value of 29.19 (not 29.20 as you might expect). However, only the new compiler issues a message to tell you that you might want to examine this statement more closely.

To understand what this message is telling you and why the result of the statement above is correct when it seems to be wrong, you need to recall these PL/I rules for arithmetic operations other than exponentiation:

  1. if either operand is FLOAT, any FIXED is converted to FLOAT
  2. if either operand is BINARY, any DECIMAL is converted to BINARY
  3. DECIMAL(p,q) is converted to BINARY( 1+log(10)*p, log(10)*q )

So, adding the FIXED BIN(31,0) variable AVAIL to the FIXED DEC(7,2) variable WORK_TOTAL will force, by the above rules, the DEC(7,2) operand to be converted to BIN(25,7).

But 12.20 cannot be exactly represented as a BIN(25,7), and is actually converted via

   ( bin(12.20,31,0) * 2**7 ) /  10**2

This yields a value that is approximately 12.195.

Then adding 17 and converting back results in 29.19.

The compiler behavior in all of the above is correct, but perhaps not what you want. If it is, in fact, not what you want, you could force the operation to be evaluated in DECIMAL by either applying the DECIMAL built-in function to the BINARY operand or by specifying the new compiler option RULES(ANS).

Under RULES(ANS), scaled FIXED BIN is not permitted and the conversion rules are more what a naive user might expect:

  if both operands are FIXED, then

    if either has a non-zero scale, any BIN becomes DEC

So when adding BIN(31,0) to DEC(7,2), the BIN(31,0) is converted to DEC(10,0) and nothing is lost.

The same considerations as detailed above also apply to the following customer code fragment:

  dcl a dec fixed(15,3) init(2500000);
  dcl zero bin fixed(31) init(0);
  if (a ¬= zero) then
     put skip edit('dec fixed ¬= Zero')(a);
  else
     put skip edit('dec fixed  = Zero')(a);

The DEC(15,3) operand gets converted to BIN(31,10).

But BIN(31,10) can hold up to 2**21 or 2_097_152.

Consequently, this conversion cannot be made successfully, and the SIZE condition would be raised if it were enabled. When the SIZE condition is not enabled, this code is in error and the CVB instruction that is generated to perform the conversion raises the ZERODIVIDE condition.

Again, the new compiler issues an appropriate message:

  IBM1099I W   FIXED DEC(15,3) operand will be converted
               to FIXED BIN(31,10). Significant digits may be lost.

Finally, using RULES(ANS) compiler option or applying the DEC built-in function to the BINARY operand would again fix this code.


Terms of use | Feedback

This information center is powered by Eclipse technology. (http://www.eclipse.org)