For performance reasons, we're looking to start using TRUNC(OPT) instead of the previous TRUNC(BIN) on one of our sites. On a previous site, we found a number of 'interesting' times when it appeared that the truncation was happening (um) 'strangely'. The manuals seem to be equally unsure, with "unpredictable results could occur" indicated 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". And this turns out not to be true quite a bit of the time.

Does anyone know a location where this discussion has taken place previously?

For example, if we use A1 PIC S9(4) BINARY VALUE 9999 as an example:
If we add 9999 to A1, then A1 (in storage) actually contains 19998 whether we use OPT or BIN. But, if we DISPLAY A1, then we get 19998 with BIN, but 9998 with OPT.
If we have field A2, which is PIC X(8192) and we do COMPUTE A1 = LENGTH of A2 + LENGTH of A2, then A1 will actually contain the value 6384 if we're using OPT, but 16384 if we're using BIN.
If we do COMPUTE A1 = 8192 + 8192, then A1 will contain 16384 whether we are using BIN or OPT (but the DISPLAY will do the truncation).
Just a couple of examples of the anomolous behaviour that we're finding.

Now, you say, that's easy! Just go through your code and find all the places where this is happening and fix them up. Unfortunately we've got over 11,000,000 lines of COBOL in our base software, let alone the additions for each of our implementations. So it's not quite as simple as it sounds - not to mention that we'd need to list the Assembler for each of the occurrences to make sure of what we were getting.

So, any pointers any previous discussions on this will save us a lot of trial and error.

Thanks. We know of the COMP-5 option, but this would negate the performance benefit of switching to TRUNC(OPT) from TRUNC(BIN) as the assembly code for procedure division statements for such variables gets generated the same, whether it is COMP-5 in TRUNC(OPT) or COMP-4 in TRUNC(BIN). What we are looking for is to see if there is any documentation on the logic of TRUNC(OPT) processing. We can see what it does in individual cases, but that doesn't help us predict what it will do in other situations.

For example, assume you are using TRUNC(OPT), you have A1 PIC S9(4) BINARY, and you have A2 PIC X(9999). What do you think this statement generates - COMPUTE A1 = LENGTH OF A2 + LENGTH OF A2
That's right! A single MVC (Move Characters) statement. The compiler (even NOOPT) works out that both elements are static, adds them together, truncates them to meet PIC S9(4) and then stores them in a halfword in the user literals. It actually does the same sort of thing if we have TRUNC(BIN), but the truncation does not occur.

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. Otherwise,
unpredictable results could occur. This truncation is performed in the
most efficient manner possible; therefore, the results are dependent on
the particular code sequence generated. It is not possible to predict the
truncation without seeing the code sequence generated for a particular
statement.

Now, I know you've read that, as you quote part of it. But when I read it, I think your question, at least the main part, goes away. The compiler, with the particular code sequence, generates the most efficient code it can, with the presumption that everything fits inside the PICture description. Obviously for similar code sequences, the same code would be generated, but identifying possible code sequences would be a lengthy, error-prone process yielding perhaps not much finally.

If I want to be "careful", I use COMP-5 - by "careful" I mean put values into a field which are sourced from an alpha-numeric. Otherwise, I'm strictly "conform to PICture", and TRUNC(OPT) works. Being "strictly" includes not assuming that it is possible to add two four-digit literals without truncation.

OK, none of that especially helps when you have 11,000,000 lines of existing code.

I'm not sure about your comments on COMP-5.

TRUNC does this:

STD - for MOVE and arithmetic expressions (note the limitation) generates code to truncate to the number of digits specified in the PICture of the receiving field. Note, if you use REDEFINES to get an alpha-num in there, and use that in a test (IF, EVALUATE, etc) then no truncation will have occured.

OPT - for MOVE and arithmetic expressions generates code that is optimal in terms of performance, either with truncation or without, depending on the particular code sequence. There may end up being superfluous high-order bits in the same field in some circumstances and not in others, but these will never affect the outcome of anything.

BIN - applies to all Cobol language, not just MOVE and arithmetic expressions. Truncation on a "boundary" only, and specific treatment in DISPLAY to take account of all bit settings (plus a couple of other small things). It gets to deal with literals that are greater than the PICture (if not too excessive).

So, if all the data, including literals, is known to conform to PICture for MOVE and arithmentic expressions, then you could change the TRUNC(BIN) to TRUNC(OPT) and not expect problems :-)

If the preponderance of the data is known to conform, but some small amount is known not to, the small amount which do not conform could be changed to COMP-5 - with the proviso that there are still rules that need to be understood and adhered to.

If it is known that not everything conforms to PICture but what does not is not itself known, you have a slightly more time-consuming situation :-)

I'm available for tele-working at reasonable rates, or in Australia on full expenses :-)

I think part of the issue is that you misunderstand what the manual means by "unpredictable results could occur." The manual is not "unclear" (as you put it) about this -- what the manual is saying is EXTREMELY clear. The manual is telling you that any given result cannot be predicted in advance if you change the TRUNC option. The result will be REPEATABLE but you cannot tell, in advance, what that result will be.

Accordingly, as Bill said, your organization has a management decision to make: to wit, does it want to spend the time and resources to determine the precise impact of the change, or accept the performance impact of leaving things the way they currently are?

I'm available for tele-working at reasonable rates, or in Australia on full expenses :-)

Robert Sample wrote:

Accordingly, as Bill said, your organization has a management decision to make: to wit, does it want to spend the time and resources to determine the precise impact of the change, or accept the performance impact of leaving things the way they currently are?

Thank you Robert (& Bill for your kind offer).

The decision to go to TRUNC(OPT) has been taken, based on the figures available in the manuals for performance gains that are possible. So we're looking at making it work successfully. Our site that we're doing this for can be doing 10's to 100's of millions of transactions a day as well as batch processing. So even a small increase in efficiency is of material benefit.

Our previous efforts (successful, eventually) relied on looking at the code to see the size of the numbers being used in each field to determine where we could be breaking boundaries imposed by TRUNC(OPT) which were not previously there. And a lot of testing.

This time (because it's us, rather than the developers) we decided to have a look at the way the code was generated and see if we could speed up the analysis process by writing a tool to do it for us (or modifying the tools that we currently have). TRUNC(STD) and TRUNC(BIN) are easy to do this for, they have consistent results which do not depend so much on the source of the numbers being moved/added to our BINARY variables. When uder TRUNC(OPT) the result in your BINARY field depends on what format it came from, whether the compiler thinks of it as a literal or not (and if you pass it to another program as a parameter it stops being a literal), whether you have OPTIMIZE on or not. And there are probably other factors.

And, of course, this only matters if the field is going to contain numbers that are approaching the boundaries of the PICture definition.

The manual is not "unclear" (as you put it) about this -- what the manual is saying is EXTREMELY clear. The manual is telling you that any given result cannot be predicted in advance if you change the TRUNC option. The result will be REPEATABLE but you cannot tell, in advance, what that result will be.

Robert,

Of course, you are correct. From our initial look at 'what happens', we have found the results to be predictable (as well as repeatable) once we have determined the specific 'situation' (i.e. input/output/compiler variables, etc). I guess that one of the problems is trying to work out the full set of 'situations' that we could come up against.

At least we've only got to work with one compiler, so we don't have that problem as well. Writing to cope with different compilers can be a nightmare.