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

Float-to-float assignments

The new compiler converts a FLOAT DECIMAL literal, such as 3.1415926E0 or 1E-02, to its internal floating-point representation solely by examining the literal's attributes and not by examining the context in which it used.

For example, 3.1415296E0 has the attributes FLOAT DEC(8), and hence the new compiler will convert it to long floating point. But, 1E-02 has the attributes FLOAT DEC(1), and hence the new compiler will convert it to short floating point.

If the literal is used in an assignment or an initial clause, the compiler will then convert, if necessary, its floating-point value to the attributes of the target of the assignment or initialization.

However, the old compilers would examine the context in which such a literal is used and convert the literal directly to the attributes of its target. The behavior of the old compilers does not strictly follow the rules for PL/I expression evaluation and can lead to different results than those produced by the new compiler. Consider this code fragment:

  dcl z float dec(06) init(0);
  dcl s float dec(06);
  dcl q float dec(17);

  s = 1e-2;
  q = s;
  put skip data( q );
  q = 1e-2;
  put skip data( q );
  q = 1e-2 + z;
  put skip data( q );

In all three assignments to q above, the attributes of the source are those of a short floating-point number, and the value of the source should be the same. However, the results of the three PUT statements under the old compilers are:

   Q= 9.999997913837432861E-03;
   Q= 9.999999999999999999E-03;
   Q= 9.999999999999999999E-03;

The results of the three PUT statements under the new compiler are:

   Q= 9.999997913837432860E-03;
   Q= 9.999997913837432860E-03;
   Q= 9.999997913837432860E-03;

This kind of difference occurs only for float literals that cannot be exactly represented (such as fractions like 1E-2 that cannot be equated to a binary fraction).

To alert you to situations such as the above, the compiler will issue message IBM1065I when it detects short-floating point literals that cannot be exactly represented.

To get the same results as under the old compilers, you would have to change your source in one of the following ways:

  1. specify the constant via the FLOAT built-in function applied to a FIXED DECIMAL literal and with the desired precision

    for example, you would specify 1E-2 as FLOAT(.01,7) to make it a long floating-point value and as FLOAT(.01,17) to make it an extended floating-point value

  2. add enough zeroes to the literal to give it the desired precision

    for example, you would specify 1E-2 as 1.000000E-2 to make it a long floating-point value and as 1.0000000000000000E-2 to make it an extended floating-point value

  3. use the new D or Q format to indicate the desired precision

    for example, you would specify 1E-2 as 1D-2 to make it a long floating-point value and as 1Q-2 to make it an extended floating-point value

Note that the first two changes in the above list would be accepted by the old and new compilers (and would produce the same results under each), but the third change would work only under the new compiler.


Terms of use | Feedback

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