COBOL

COBOL

COBOL

COBOL is responsible for the efficient, reliable, secure, and unseen day-to-day operations of the world's economy.


#Programminglanguages
 View Only
Expand all | Collapse all

Using TRUNC(OPT)

  • 1.  Using TRUNC(OPT)

    Posted 05/26/16 06:49 PM

    Does any one have a specific example of a case where TRUNC(OPT) generates different code from TRUNC(STD)?

    Or perhaps I should be asking a different question.  Are there any examples of a case where the results will be different, depending on which of these two options is used?

    Thanks, Frank.

    fswarbrick


  • 2.  Re: Using TRUNC(OPT)

    Posted 05/27/16 08:00 AM

    To use TRUNC(OPT), you contract with the compiler to never, ever, not "conform to PICture" for binary fields (excluding COMP-5).

    Assuming you stick to the contract, the results for TRUNC(OPT) and TRUNC(STD) will be the same, the TRUNC(OPT) will produce the same output "faster".

    If you don't "conform to PICture", always, for those fields, your TRUNC(OPT) results will be wrong, and thus different from TRUNC(STD).

    Note, if not conforming to PICture then the results won't necessarily be wrong "all the time", but you won't ever want to rely on a code-sequence that "happens to work". If you do rely on it, never attempt to migrate that program :-)

    As for examples, pick a program which uses some binary fields, compile with STD and OPT, note the change in the number of lines on the listing.

    BillWoodger


  • 3.  Re: Using TRUNC(OPT)

    Posted 05/27/16 11:54 AM

    The reason I bring this up is that we currently use (and have always used, as far as I know) TRUNC(STD), but if we turn on the E. COBOL v5.2 RULES(NOLAXPERF) compiler option we get the following in every compile:

         IGYSC2255-W   **RULES(NOLAXPERF)** Compiler option "TRUNC(STD)" was in                    effect and could produce a less efficient program                           compared to option "TRUNC(OPT)".  Compiler option                           "TRUNC(OPT)" could result in better run-time performance.                   Please note: Investigate side effects before making                         changes to compiler options.                             

    Not to mention this one:

         IGYSC2251-W   **RULES(NOLAXPERF)** Compiler option "NUMPROC(NOPFD)" was                   in effect and could produce a less efficient program                        compared to option "NUMPROC(PFD)".  Compiler option                         "NUMPROC(PFD)" could result in better run-time                              performance.  Please note: Investigate side effects                         before making changes to compiler options.               

    Obviously I am hesitant to turn on either TRUNC(OPT) or NUMPROC(PFD) at a global level, since they both seem likely to me to cause behavior changes in some programs.  Worrying about going from NUMPROC(MIG) to NUMPROC(NOPFD) is concerning enough for me!  Crying

    Personally, my thought at this time is that COMP/BINARY is of little real use, and if you want a "true binary" data item one should use COMP-5.  Is that a reasonable way to go?  And if you want true "picture conformance" with non-DISPLAY data you can use COMP-3 / PACKED-DECIMAL.

    Of course I'd really like to see the (new) standard COBOL usages BINARY-CHAR, BINARY-SHORT, BINARY-LONG, which would be an even more "true binary" then COBOL 5, including behavior for ON SIZE ERROR.  Don't know how realistic it is to expect IBM to implement this any time soon.

     

    fswarbrick


  • 4.  Re: Using TRUNC(OPT)

    Posted 05/27/16 01:30 PM

    Ah. OK. Yes, you are correct, it would be an absolutely terrible idea to glibly switch from TRUNC(STD) to TRUNC(OPT) en masse, or switch from NUMPROC(MIG) to NUMPROC(PFD).

    However, if you have a "feel" for the systems that they are generally good (conforming to PICture for binary and packed-decimal (ie including signs)) the a Migration may be a "good" time to do it.

    But, if it is known that the data sometimes has F-signs in S-PIC fields, or that loops routinely rely on truncation for binary fields when it seems convenient, then you'd get lots of differences. Lots.

    Data good and practice good, use TRUNC(OPT) and NUMPROC(PFD). Else use what you have already (where possible...) and hope that is not TRUNC(OPT) and NUMPROC(PFD) (known not to be the latter in your case).

    Native-binary is something. I'd not use it, except where needed. When COBOL truncates, it is a decimal truncation (and that's in the Standard). COMP-5 (native binary) truncates to field-size - but must do a decimal truncation (can't just chop of excess bits).

    That is much better in V5 plus (only truncates when necessary). However, checking for truncation is also more necessary. PIC 9 multiplied by PIC 9 has to check for truncation always in COMP-5, only when needed (size of receiver(s) for other binary).

    So native-binary generally "performs" worse than COBOL's decimal-limited binary.

    Packed-decimal instructions are traditionally "slow" ones. V5+ and up-to-date hardware allow for the use of new instructions (Decimal Floating Point), which even give strong results on USAGE DISPLAY numerics.

    It still see no point, other than the word of the standard, in the other binary data-types. I'm still open to be convinced.

    I would dislike the messages appearing all the time. I think there should have been one "laxperf" for compiler options, which can be run against each "standard" compile at a site periodically, and another one of the "code" which is considered to be lax, which you can consider using all the time, depending...

    BillWoodger


  • 5.  Re: Using TRUNC(OPT)

    Posted 05/27/16 04:10 PM

    >> Ah. OK. Yes, you are correct, it would be an absolutely terrible idea to glibly switch from TRUNC(STD) to TRUNC(OPT) en masse << We had a discussion a few weaks ago about the number of digits in binary items. My opinion was and is still that binary items always should be defined with that precision the binary fields have; i.e. 2 bytes defined with PIC S9(04), 4 bytes with PIC S9(09) (or S9(08)). In that case the way from TRUNC(STD) to TRUNC(OPT) will have _no_ , yes _no_ risk! We've done that with a whole application with cpu-optimization of 2%. I have no experience with changing the option if the definitions of fields will not match. But I _assume_ that there will also be no risk.

    TRUNC(STD) will work exactly with that number of digits which are defined. TRUNC(OPT) guaranties the same results to that number of digits. It will generate different results if and only if the results would be greater. Example: pic s9(04) binary with the addition 9999 + 1 give 0 with TRUNC(STD) and 10000 with TRUNC(OPT). If your application works correct with TRUNC(STD) it will also do so with TRUNC(OPT) - except you had coded "wrong" code.

    It's different with NUMPROC(noPFD). Assuming prog A with a numeric field S9(02) and a move zero to it. Prog B receives that field but has the definition 9(02) without a sign. Assuming also a test on that field on numeric. With NUMPROC(NOPFD) the numeric test will be ok, with NUMPROC(PFD) it will not. (I had that behaviour with V4.x and I think (but I don't know) it will be the same with V5 and V6.) Therefor: be careful with NUMPROC changes.

    But: The behaviour of the programs can also change with using different OPT-Options. Example: A Move from a numeric field to the other _can_ be a MVC! Did you know that? Where do you use those fields which had that MVC before? Yes, you don't know. Nearly we all had changed the Options to OPT(FULL) how it's called in V4.x. And the application runs correct. Why do you not change NUMPROC to PFD and test your application very well? The optimization well be about 1% in CPU. That example i mentioned we had in one company and the different results were noticed "at once". Anyway: be careful and test. The migration would be a wonderful possibility to optimize your applications. ;-)))

     

    And: I am very proud that the compiler gives those messages you, Frank, showed. For several years we have adjured Steve Miller in meetings that performance hints should be given. The compiler "knows" all that stuff. I wait for that message that packed fields with a even number of digits erases a message. ;-)

     

     

    RalfSeidler


  • 6.  Re: Using TRUNC(OPT)

    Posted 05/27/16 04:51 PM

    Well...  I agree and disagree, at least for the TRUNC and NUMPROC messages.  If I am not mistaken, if you want to be 100% compliant with "standard COBOL" you must specify TRUNC(STD) and NUMPROC(NOPFD) (not sure on the latter...).  The fact that there are options that perform better but are non-standard is interesting to know, but annoying to see when you've made the decision to follow the standard, even if it "degrades" performance.

    fswarbrick


  • 7.  Re: Using TRUNC(OPT)

    Posted 05/28/16 04:31 AM

    TRUNC(STD) would be Standard. NUMPROC is irrelevant for the Standard, as the representation of signs is down to the implementor.

    BillWoodger


  • 8.  Re: Using TRUNC(OPT)

    Posted 05/28/16 04:24 AM

    >"My opinion..."

    Well, it's an opinion, and it is commonly-held. As long as you abandon any idea of stating that it is "better for performance", which you seem to have done, then OK.

    As long as the code generated for TRUNC(STD) does not actually truncate anything (and no, there is no handy indication of this) then  identical results will be obtained, faster, with TRUNC(OPT). If STD actually truncates, then the code generated by TRUNC(OPT) will be correct (it is not the compiler's fault) but the program will be wrong, often quite subtly.

    That includes "deliberate" truncation. MOVE of a PIC 9(4) to a PIC 9(2) with STD, will truncate for all values above 99. With TRUNC(OPT), the whole thing will  (likely) be MVC'd (I say "likely", because if it is more convenient (for the compiler) to truncate at that particular time, it will).

    So, as long as a program does not rely on truncation (knowingly or not) for (non-COMP-5) binary items, TRUNC(OPT) can be used without worry.

    Is this affected by the size the field is defined as? No. PIC 9(4) can as easily break as PIC 9, if you let it happen. MOVE a (binary) PIC 9(8) (or 9(9) if you want to extend the execution time) to a PIC 9(4) and you have the problem. And no, it makes no difference to the potential for truncation to have the fields signed.

    If you feel you have that guarantee you mention for TRUNC(OPT), post a link to the manual, please.

    It is not a case of whether a program works with STD. It is whether the program does not truncate. Whether the data always conforms to the PICture.

    For NUMPROC, it is the same. If all your data conform to PICture, you can switch straight to NUMPROC(PFD). If they don't, you must use NOPFD.

    If all your binary data and decimal data conform to PICture, a Migration is a good time to make the switch.

    If you don't have a good feeling about the data, then a Migration is a bad time to make the switch unless a decision is made to deal with issues as they arise. It is bad, since a large number of your different behaviours noted will be down to those compiler-option changes - self-inflicted.

    Different observed behaviour for OPT(1/2) you report to IBM. Different code generation but result is the same, does not count for anything. That's the natural result of optimisation.

    For the messages. The problematic ones are the "compiler option" ones. As a programmer working on a particular system, it is not down to you what the compiler options are. It is possible that you can't even change them. They will be the same for all programs in the system (generally). So, if you have 1,000 programs, each and every time you compile any program you get a diagnostic message that you can do nothing about.

    OK, what's bad about that. Well, it encourages the ignoring of messages. "Oh, we always get RC=4 when we compile, don't bother with the messages". That's bad.

    I don't know if the severity or presence of those particular messages can be changed with an MSG exit for the compiler. You could also use the listing exit to suppress the messages. But wouldn't it be simpler if the compiler options (which asfter all could remain unchanged until obsoleted by a new compiler release) checking could be specified separately to the "code" checking for RULES?

    BillWoodger


  • 9.  Re: Using TRUNC(OPT)

    Posted 05/28/16 09:53 AM

    >> MOVE a (binary) PIC 9(8) (or 9(9) if you want to extend the execution time) to a PIC 9(4) and you have the problem. << Jep, you're right. And I hope that the compiler will rise a message for that very soon. PL/1 has this message for many years!

    >> If you feel you have that guarantee you mention for TRUNC(OPT), post a link to the manual, please. << Look at Programing Guide Compiler Options TRUNC (Have also a look on the performance Tuning paper with compile option / SHARE_2015_03_S16613_Coding_for_performance.pdf: TRUNC(STD) Should never be used! Use TRUNC(OPT).): "Use the TRUNC(OPT) option only if you are sure that the data being moved into the binary areas will not have a value with larger precision than that defined by the PICTURE clause for the binary item." I think exact that is the case when you use TRUNC(STD) only with s9(04/9) binary (and you will not have moves from s9(9) to s9(4) and no "complex" arithmetic on binary fields). I've read the word guarantee anywhere but I didn't find it for now. Perhaps SHARE, perhaps GUIDE.

    Messages: _I_ want to have compiles with RC=0. And it cripples my mind if I hear something like: "Oh, we always get RC=4 when we compile, don't bother with the messages". :-((( And those messages help me to optimize my code - - - better code and code more correct.

    >>migration (to V5/V6) is a bad time ... trunc/numproc << Yes, you're right and no, you're not right. I wouldn't mix both "projects" at once. But because you are in a migration with many many tests (I hope so!) you have the _possibility_ to expand the migration a little bit. ;-))

     

    Have all a nice weekend - with no thunderstorm like we have now in Bingen/Rhein. :-)

    RalfSeidler


  • 10.  Re: Using TRUNC(OPT)

    Posted 05/30/16 04:33 PM

    BINARY PIC 999, BINARY PIC 99. With TRUNC(STD) you would get truncation. With 9(4) and 9(4) you would not. So it is "difficult" to argue that just making everything the "right" size relieves all known issues. You don't get the truncation, which was presumably wanted.

    To be certain to get the (desired) truncation with either set of definitions, you need to MOVE it to a 9(2). Preferably packed-decimal. And then MOVE that to the 9(2) or 9(4) BINARY. Ah, that'll get more gnashing of teeth, and the compiler message from NOLAXPERF. You really want to MOVE it to a USAGE DISPLAY 99?

    Yes, with TRUNC(OPT) and a MOVE which would otherwise cause truncation (except for the OPT, when it will only truncate when convenient in the code-sequence) a message may be useful. Except, do you ever really "truncate" (deliberately) in BINARY fields? I can't really remember doing that, but that doesn't mean it doesn't happen.

    Which leaves the "overflow". Which can happen (ADD 1 TO .... which already is all nines) but only due to bad code (even if deliberate, it is bad).

    With no "bad code" for ADDing (or other maths) and no deliberate truncation directly in binary fields, then TRUNC(STD) = TRUNC(OPT) except the latter is faster.

    However, there is absolutely no way that anyone will guarantee that, without the proviso stated.

     

    BillWoodger


  • 11.  Re: Using TRUNC(OPT)

    Posted 05/29/16 08:47 PM

    Biil, that is all very good stuff to consider.  And honestly, even though its "obvious" I had never really considered the fact that TRUNC only affects, well, truncation.  So in the case of TRUNC(STD) there is "a lot" of extra code in place to handle truncation, when generally the truncation path is never even taken (but the compiler can't know that, of course).  But your point about behavior being the same as long as your (programmatically) guarantee that your code will never attempt to overflow the field beyond the specified PICTURE then it doesn't matter that if you did overflow the picture you could get non-standard with TRUNC(OPT) is well taken.  Of course there is no way I could be confidant of every program in our shop being compliant in this matter!

    Which brings me back to COMP-5.  You really lose me (so far) with your apparently don't care for it all, in general.  You say: "Native-binary is something. I'd not use it, except where needed. When COBOL truncates, it is a decimal truncation (and that's in the Standard). COMP-5 (native binary) truncates to field-size - but must do a decimal truncation (can't just chop of excess bits)."  I'm not sure what you mean here.  Here are some observations...

    A program reads in a PIC 9(5) DISPLAY field and moves it to a PIC 9(4) COMP field.  (Yes, I'm not sure why someone would actually do this, but...).  Let's say this input is 98765.  Here are the results:

    • TRUNC(STD) = 8765 (the sender value is truncated to 4 digits as part of the "move").

    • TRUNC(BIN) = 33229 (98765 = 0x181CD, which is truncated to 2 bytes 0x81CD, which is 33229 decimal).

    • TRUNC(OPT) = 3229 (sort of).  The value stored in the 2 byte field is x81CD (33229), but when displaying it the runtime truncates to four decimal digits).

    • A field defined COMP-5 will in all cases behave just as a COMP with TRUNC(BIN).

    Another "interesting" feature of the TRUNC(OPT) example above is that if you move it back to a PIC 9(5) DISPLAY it will move the entire 33229, not just the 3229.  So that's fun!  Oops

    To me, for things like counters and "length fields", at least, this is why COMP-5 is preferable to COMP.  It's behavior is predictable (assuming you are not expecting "COBOL truncation", but rather binary truncation), and the generated code is optimal.  And perhaps this in and of itself is why the "true binary" COBOL data items (BINARY-CHAR, BINARY-SHORT, BINARY-LONG) should be supported.  First, no PICTURE clause to confuse the issue.  Second, ON SIZE ERROR behavior matches other behavior (ON SIZE ERROR for COMP-5 data items respects the COBOL PICTURE, but no other COMP-5 behavior respects the PICTURE).

     

    fswarbrick


  • 12.  Re: Using TRUNC(OPT)

    Posted 05/30/16 05:18 PM

    OK, "native binary" first.

    The "problem" with native-binary is the performance. The performance is improved with V5+, as the dread divide (and associated code) is only done now when needed. It still "looks" like a lot of code, but some of the code will only be executed when needed, and assuming that no actual overflow occurs, will never be executed. So that's very good.

    There's a very useful discussion of this in Chapter 8. Coding techniques to get the most out of V6 in the V6 Performance Tuning Guide, although I'm wondering if there is a typo in and other references to COMP-5.

     

    COMP-5 is not always slower than STD/OPT:

    Although TRUNC(BIN) enables more efficient code when storing out a COMPUTE or MOVE result it continues to significantly harm the performance when these data items are used as input to arithmetic statements (as the compiler must assume the max 2,4,8 byte size). V6 optimizes the correction code for TRUNC(STD) so the performance benefit of TRUNC(BIN) has been reduced slightly.

    In specific cases where data naturally exceeds the PICture (CICS, DB2, "integer" data from programming languages with that) then use COMP-5 for the relevant fields. Specifying TRUNC(BIN) just applies COMP-5 to all BINARY types, and whilst you have all the digits you may need, you have also affected the performance of everything which doesn't need the extra digits (beyond the PICture).

    Neither TRUNC(OPT) not TRUNC(STD) affect COMP-5 fields.

    This:

    TRUNC(STD) instructs the compiler to always correct back to the specified PICTURE clause and allows the compiler to assume that loaded values only have the specified number of PICTURE clause digits.

    Indicates the importance of knowing that you source field conforms to PICture unless using COMP-5. As with USAGE DISPLAY and PACKED-DECIMAL the compiler does not generate code to truncate the source, only the target/receiving field. The compiler assumes that COBOL code generated by the compiler has created all source fields that it uses. If an original source value does not conform to PICture, whether using OPT or STD, then "interesting" things will/may occur.

    So, no, except for "moves" (there may be other exceptions, I don't know, but maths is bad and ADD 1 is maths) the generated code for COMP-5/TRUNC(BIN)/native-binary is not optimal.

    When I say "use COMP-5 when needed" I mean "use COMP-5 when that source value can, by design, exceed the PICture of a COBOL binary field of that byte-size".

    Of course, you are free to use COMP-5 for everything, or to use TRUNC(BIN). You just have to accept the performance hit. I know of two sites who changed from TRUNC(BIN) to TRUNC(OPT) and were very happy with the results (in terms of reduced running costs). That is not an easy change to make either. It needs care. Anything that requires the BIN must be changed to COMP-5.

    With your TRUNC(OPT) example, you just can't do that. It immediately breaks the contract with the compiler, and the results are all your own fault. You can't promise not to exceed the bits set for the maximum value represented by the PICture, and then complain when you do that :-)

    With the new names, it multiplies the issue with native-binary. On the positive side, it would allow access to a one-byte binary, but since there's no machine instruction that does direct maths on a one-byte binary, the compiler would end up doing what we do already ("pretend" it is a half-word and put the one byte in the first or second byte, ensuring the other is zero).

    Would it make the code more portable? Not really, since it is down to the implementor to define how those descriptions are stored.

    Yes, the ON SIZE ERROR is an issue. I can't recommend using it with COMP-5 at all :-)

    However, if IBM were to "fix" it, how many programs would "break"? We can't even begin to guess.

    I always make sure my fields are big enough, and don't use ON SIZE ERROR (subject to site standards, of course...).

    BillWoodger


  • 13.  Re: Using TRUNC(OPT)

    Posted 05/31/16 08:43 PM

    (I can't figure out how to do the "inline quoting" like you did.)

    So here's my deal.  The documentation (the Performance Tuning Guide) seems to say one thing (don't use COMP-5 unless you have a specific need for it), but when I look at the generated code I see no reason for this.  Take, for example, your comment about the "dreaded divide".  My observation is that the only time code is even generated to use the divide to do the truncation is for COMP with TRUNC(STD).  For example, using COBOL V5.2 with TRUNC(STD) and OPT(0) (not sure if the latter matters, but its a good baseline):

    05  cob-bin-u               pic 9(4)    comp.  
    05  tru-bin-u               pic 9(4)    comp-5.

    000023:  003210     add 1 to cob-bin-u                                                    
       0001EE  E300 8030 0095     000023            LLH     R0,48(,R8)            #  COB-BIN-U
       0001F4  A70A 0001          000023            AHI     R0,0x1                            
       0001F8  A7F8 2710          000023            LHI     R15,0x2710                        
       0001FC  1010               000023            LPR     R1,R0                             
       0001FE  C21F 0000 2710     000023            CLFI    R1,X'00002710'                    
       000204  A744 0006          000023            JL      L0081                             
       000208  8C01 0020          000023            SRDL    R0,32                             
       00020C  B997 000F          000023            DLR     R0,R15                            
       000210                     000023  L0081:    EQU     *                                 
       000210  4000 8030          000023            STH     R0,48(,R8)            #  COB-BIN-U

    000024:  003220     add 1 to tru-bin-u                                                    
       000214  E300 8032 0095     000024            LLH     R0,50(,R8)            #  TRU-BIN-U
       00021A  A70A 0001          000024            AHI     R0,0x1                            
       00021E  4000 8032          000024            STH     R0,50(,R8)            #  TRU-BIN-U

    The "COBOL" binary field has the dreaded divide (but only if the result of the addition is 10000 or more).  The COMP-5 simply has "load logical halfword to register", "add halfword immediate value 1 to register", and "store halfword from register".  Call me crazy but COMP-5 appears to me to be much better (performance-wise).

    Now let's do TRUNC(BIN).  I'll only show the result for the COMP field, because as you say, COMP-5 is not affected by the TRUNC option:

    000023:  003210     add 1 to cob-bin-u                                                    
       0001EE  E300 8030 0095     000023            LLH     R0,48(,R8)            #  COB-BIN-U
       0001F4  A70A 0001          000023            AHI     R0,0x1                            
       0001F8  4000 8030          000023            STH     R0,48(,R8)            #  COB-BIN-U

    So the behavior of COMP with TRUNC(BIN) is the same as COMP-5, as expected.  Also better than TRUNC(STD).  Now let's do TRUNC(OPT):

    000023:  003210     add 1 to cob-bin-u                                                    
       0001EE  E300 8030 0095     000023            LLH     R0,48(,R8)            #  COB-BIN-U
       0001F4  A70A 0001          000023            AHI     R0,0x1                            
       0001F8  4000 8030          000023            STH     R0,48(,R8)            #  COB-BIN-U

    Exactly the same as TRUNC(BIN) and COMP-5 (in this case, at least).  So why does the Tuning Guide seem to indicate differently?  It would be nice to know what the actual code is that they used for their tests.

    I'm still looking for an actual example (code!) where COMP-5 is not at least as good as COMP with any of the TRUNC options.  All of my tests so far have been with binary fields of a fullword or less.  I'm just now looking at ones that are greater than that, and it looks like this may be where performance for TRUNC(OPT) is better than COMP-5 and COMP with TRUNC(BIN).  More on this tomorrow.

     

     

    fswarbrick


  • 14.  Re: Using TRUNC(OPT)

    Posted 06/01/16 01:49 AM

    For the in-line quoting I can see an icon on the edit bar on the post, to the left of the backward-Ps. Mouse-hovering over that describes it as "blockquote".

    I don't have access to V5+, so can only go by the documentation.

    My "guess" about what you are seeing is that you are being "optimised out". The V5+ optimiser is immensely more clever than the one before. I think it is aware that you have source fields with literal values that are unchanged, and thus it "knows" that ADD 1 in that particular piece of code does not need to even check for potential truncation.

    My code never truncates (unless I want it to). When I see the generated output, my coding-sheets weep at the unnecessary torture to check-and-correct for "truncation" that is impossible. Good for the new optimiser!

    Put VOLATILE on the definitions of your fields, that should stop the optimiser in its tracks. For short pieces of demo-code, consider OPT(0) at least in the first instance.

    COMP-5/TRUNC(BIN) truncate to field-size (two, four or eight bytes).

    This means, even with a simple ADD 1, the compiler has to assume (subject to optimiser-knowledge) that a field already contains the value 65535 or +32767/-32768.

    Which therefore always requires that any intermediate results are "the next size up" (if the source values are two bytes, intermediates have to be four, if four bytes, eight, and if eight, 16!).

    There's more discussion from here late last year: https://www.ibm.com/developerworks/community/forums/html/topic?id=ae9ef6bc-6e4e-43f8-a814-e66bea25fb8c&ps=25

    If you have PIC 99 and PIC 999, algebraically, the result field has a maximum size of six digits. If you multiply those with OPT/STD to a PIC 9(6) there is no code for truncation, as there can't be any. Do the same with COMP-5/TRUNC(BIN) and the code for truncation is required, because of the required (minimum 10 digits) intermediates.

    The required truncation can't bluntly chop off excess bits, because it is is a binary representation of a decimal number and COBOL must truncate to a decimal (in a PIC 99 a result of 239 will be truncated to 39, as your previous examples show). You can't just get rid of excess bits. Hence the divide, and the code to set that up, and get it back to a binary value.

    Note: my schemes to defeat the previous optimiser are not clever enough to defeat the current optimiser. OPT(0) also includes some optimisations, which was not the case with NOOPT.

    BillWoodger