It is generally best to avoid scaled FIXED BINARY since its use generally causes the compiler to produce less efficient code. Additionally, in some conversions of scaled FIXED BINARY to FIXED DECIMAL, the new compiler may produce a different (but more accurate) result than the old compiler.
For example, consider the following code
dcl i fixed bin(15) init(290); dcl s fixed bin(31,16); dcl d fixed dec(15,12); d = i / 365; put skip data( d ); s = i / 365; d = s; put skip data( d );
The results of the two PUT statements under the old compilers are:
D= 0.794509887700; D= 0.794509887700;
The results of the two PUT statements under the new compiler are:
D= 0.794509887695; D= 0.794509887695;
Note that while the second assignment above clearly involves a conversion of scaled FIXED BIN to FIXED DEC, the first assignment also involves such a conversion since the attributes of the expression i / 365 are, by the PL/I rules for expression evaluation, FIXED BIN(31,16).
To understand what is happening here, it will help to look at the contents of the variable s after it is assigned the result of the divide. s will then hold the hex value 0000CB65. If viewed as a FIXED BIN(31,0) number, this would be the value 52069, but since it has scale factor 16, it represents the value 52069/2**16. That value is mathematically equivalent to 52069*5**16/10**16. So, to convert it from base 2 to base 10, the compiler multiplies the value by 5**16 (or 152587890625). That would produce a FIXED DEC value with scale factor 16; hence to produce the target result with scale factor 12, the last 4 digits are dropped.
As can be verified on a calculator, 52069 times 5**16 is 7945098876953125, and dropping the last digits yields the result produced by the new compiler.
The reason the old compiler produced a different result is that its generated code multiplied s not by 152587890625, but 152587890626. This leads to a less accurate result.
You can avoid this problem entirely by insuring that all divisions that could yield a fractional result are performed in decimal. Using the DECIMAL built-in function is one easy way to do this. For example, if, in the first assignment above, the expression i / 365 were changed to dec(i) / 365 , the result of the assignment would be 0.794520547945.
To alert you to situations such as the above, the compiler will issue message IBM2810I when it detects conversions of scaled FIXED BIN to FIXED DEC.