Please, post my message in comp.lang.pl1 - I haven't permission to do it by myself... Sorry to bother you, really.. 
Author Message
 Please, post my message in comp.lang.pl1 - I haven't permission to do it by myself... Sorry to bother you, really..

Quote:

>Hello John,
>  I am so sorry to bother you, but don't you mind to send my message
>  in comp.lang.pl1? Our network administrator destroys new transport
>  on our server, and all of us only can read messages there. Please,
>  help me...
>  Here is the message:

>  Hello, All!

>Maybe you don't believe me, but all what I will tell you is truth. Really.
>So, there is a simple program:
>TSTPL: PROC OPTIONS(MAIN);    
> DCL A DEC FIXED (5);            
> A=1000+15/3;                    
> PUT DATA(A);                    
> END TSTPL;                      
>I tried to run it in VM/SP 6.18 with PLIOPT version 2.3.0. Here is the compiler message:

>5668-910 IBM OS PL/I OPTIMIZING COMPILER  VER 2 REL 3 MOD 0            
>5668-910 IBM OS PL/I OPTIMIZING COMPILER   TSTPL: PROC OPTIONS(MAIN);  
>NO MESSAGES OF SEVERITY W AND ABOVE PRODUCED FOR THIS COMPILATION      

>MESSAGES SUPPRESSED BY THE FLAG OPTION:  1 I.                          
>COMPILE TIME    0.00 MINS        SPILL FILE:     0 RECORDS, SIZE  4051  
>END OF COMPILATION OF TSTPL                                            

>Here is the assembler listing of the third statement (A=1000+15/3;)

> * STATEMENT NUMBER           30                            
> 000096  F1 21 D 098 3 050         MVO   WKSP.1+32(3),80(2,
>                                         3)                
> 00009C  D7 06 D 09A D 09A         XC    WKSP.1+34(7),WKSP.
>                                         1+34              
> 0000A2  D1 00 D 0A0 3 051         MVN   WKSP.1+40(1),81(3)
> 0000A8  FD 80 D 098 3 052         DP    WKSP.1+32(9),82(1,
>                                         3)                
> 0000AE  D2 07 D 0F0 D 098         MVC   240(8,13),WKSP.1+3
>                                         2                  
> 0000B4  F1 32 D 098 3 053         MVO   WKSP.1+32(4),83(3,
>                                         3)                
> 0000BA  D7 06 D 09B D 09B         XC    WKSP.1+35(7),WKSP.
>                                         1+35              
> 0000C0  D1 00 D 0A1 3 055         MVN   WKSP.1+41(1),85(3)
> 0000C6  FA 97 D 098 D 0F0         AP    WKSP.1+32(10),240(
>                                         8,13)              
> 0000CC  F8 79 D 09A D 098         ZAP   WKSP.1+34(8),WKSP.
>                                         1+32(10)          
> 0000D2  F1 20 D 0B8 D 09A         MVO   A(3),WKSP.1+34(1)  
> 0000D8  D1 00 D 0BA D 0A1         MVN   A+2(1),WKSP.1+41

>And here is the result:
>IBM482I  'ONCODE'=0310  'FIXEDOVERFLOW' CONDITION RAISED          
>    IN STATEMENT 3 AT OFFSET +0000CA IN PROCEDURE WITH ENTRY TSTPL

>The error is in the only one calculating statement. If I write it as
>A=1000+0015/0003;                    
>everything will be OK.
>I have tested it in older compilers and environments - OS/VS (compiler V1), in VM/ESA 2.2.0
>and so on, but the result was the same.
>How can I solve this problem?

>Best regards,
>Alexander Kostyrko (with great hope)

>p.s. yes, I know, my English isn't perfect, but I am working on it...

This is a classic beginner's mistake.

In the first version, you are dividing a FIXED DECIMAL(2,0) by a FIXED
DECIMAL(1,0).
According to PL/I precision rules, the result of this is FIXED
DECIMAL(15,13).  How is
this arrived at?  15 is the maximum precision possible for FIXED DECIMAL
with this particular
compiler.  The largest possible quotient of FIXED DECIMAL(2,0) divided by
FIXED DECIMAL(1,0) is 99/1, or 99.  So the compiler allows two integer
digits, and allocates
all the rest to the fraction -- 15,13.  So your actual result is
05.0000000000000.  Then you add
1000 (FIXED DECIMAL(4,0)) to that.  The result would be FIXED
DECIMAL(18,13), if that
were possible, but, since it isn't, it tries to fit 01005.0000000000000
into FIXED DECIMAL(15,13),
and fails.

In the second version, you are dividing a FIXED DECIMAL(4,0) by FIXED
DECIMAL(4,0).
In this case, the result is FIXED DECIMAL(15,11),  0005.00000000000.  Adding
1000 to this gives 1005.00000000000 (FIXED DECIMAL(15,11)).

A = 1000 + 0015 / 3;

would have worked just as well.

However, this is not a good solution, because it is confusing.

This is a basic problem with fixed-point, non-integer arithmetic.  There
is no possible set
of rules for the language to follow that will not either cause
FIXEDOVERFLOW in some
cases or give incorrect results in some cases.  Changing the upper limit
of precision to some
number larger than 15 wouldn't help; the result of a fixed-point
division is always given the
upper-limit precision, whatever that is.  Most languages "solve" the
problem by supporting
only integers and floating-point numbers.  COBOL "solves" the problem by
not having
any rules; the compiler designer is free to do whatever he wants; that's
why all books of
advice about programming in COBOL tell you never to use the COMPUTE
statement -- it
gives essentially random results.  Ada solves the problem by forcing the
programmer to
specify what precision he wishes the result of a division (or
multiplication) to be when he
is working with fixed-point, non-integer data.  

The safe thing to do in PL/I is to use the same strategy as Ada.  PL/I
has MULTIPLY
and DIVIDE built-in functions (ADD, too, and also SUBTRACT on some
compilers)
that allow you to control the precision of your result.

A = 1000 + DIVIDE (15, 3, 6, 4);

for example, will divide 15 by 3 and put the result into FIXED DECIMAL(6,4).
That will give a result of 05.0000.  When that is added to 1000, the
final result will
be 01005.0000.

Instead of DIVIDE, you can use the PREC or FIXED or DECIMAL built-in
functions.

A = 1000 + PREC (15 / 3, 6, 4);

The numbers you use don't have to be 6 and 4.  But the last number must
be no more
than 11, so that the final result will fit in FIXED DECIMAL(15,11).


    "The poor have sometimes objected to being governed badly;
    the rich have always objected to being governed at all."
    -- G. K. Chesterton, "The Man Who Was Thursday"



Mon, 09 May 2005 03:10:21 GMT  
 
 [ 1 post ] 

 Relevant Pages 

1. Please, post my message in comp.lang.pl1

2. number of messages posted in comp.lang.lisp

3. --- comp.lang.clarion guidelines: please read before you post (weekly notice)

4. --- comp.lang.clarion guidelines: please read before you post (weekly notice)

5. --- comp.lang.clarion guidelines: please read before you post (weekly notice)

6. --- comp.lang.clarion guidelines: please read before you post (weekly notice)

7. --- comp.lang.clarion guidelines: please read before you post (weekly notice)

8. Administrator: Can't delete me comp.lang.ada ng message

9. No posting about ISE's new product to comp.lang.c++ and smalltalk

10. FINAL CALL FOR VOTES: comp.lang.pl1

11. CFV: comp.lang.pl1 -- PL/I newsgroup

12. PL/I Newsgroup comp.lang.pl1 exists now

 

 
Powered by phpBB® Forum Software