COMPUTE: Compiler option to abend if non-numeric input?

Hello Friends.

Currently at my IBM Mainframe 390 installation, Natural does not always abend if one of the inputs to a COMPUTE statement is non-numeric.

The same type of conversion to numeric, e.g spaces to zeroes, as discussed in a prior thread takes place.

Is there a compiler option that will prevent the conversion from alpha to numerics and force an abend if this situation occurs ?

Is the Optimizer Compiler (NOC) involved ?

My understanding was that the automatic conversion from alpha to numeric (in a numeric field) was implemented by SAG for compiler optimization purposes - though I have a hard time seeing why.

However, my site has recently implemented the compiler option to prevent automatic conversion in the case of a MOVE instruction. But apparently, it is still happening for COMPUTEs and possibly the other calculation instructions.

PLEASE! DOES SOMEONE KNOW OF A COMPILER OPTION TO PREVENT THIS CONVERSION IN A COMPUTE STATEMENT ?

It’s always at the programmers responsibility to avoid computation with non-numeric characters.
Natural itself doesn’ t allow computation with variables, if they are not defined in an adequate format. Else at compilation time the program will receive an error, e.g. NAT0295.

But it is possible that Natural computes with non-numeric characters. That’s the case when Redefines are involved.

DEFINE DATA LOCAL
1 #ALPHA (A2)
1 REDEFINE #ALPHA
2 #NUM (N2)
END-DEFINE

The program inputs #ALPHA = ‘A9’. That is in hex: C1 F9. Natural checks whether the value is compatible to the variable’s format and if the value is written to the main memory. When you pick up this value with a Redefine (N2), Natural doesn’t check again, whether the format and the value are compatible. This would slow down performance. Therefore it is the programmer’s responsibility to use Redefines properly.

Natural doesn’t convert alphas to numerics. Natural takes, like other programming languages, the right halfbyte of a character for computation because for decimals the left halfbyte is always F (EBCDIC) or 3 (ASCII). Computation is faster when the left halfbyte is left out.
In this example, when you COMPUTE #NUM = #NUM + #NUM the result will be 38.

If the right halfbyte isn’t numeric the program will receive at runtime an error or Natural will abend (#ALPHA = ‘A*’. The hex value is: C1 5C).

Thanks, Helmut, for your reply. What you wrote makes sense.

However, this particular problem occurred when SOMEHOW, SOMEWHERE bad data ended up in a numeric field ON A FILE. You know what they say [and this doesn’t apply only in our business], “SH*T HAPPENS!”

When the record is read, the field is used in a COMPUTE. There is NO REDEFINE INVOLVED.

I was hoping there was a COMPILE OPTION that would force an abend BECAUSE IN FINANCIAL SYSTEMS this is intolerable …

Why don’t you just check if the A variable contains a valid numeric value?

DEFINE DATA LOCAL
1 #ALPHA (A2)
1 REDEFINE #ALPHA
2 #NUM (N2)
END-DEFINE 
IF #ALPHA IS (N2)
  PRINT "YES"
ELSE
  PRINT "NO"
END-IF
END

I think a global compiler switch would cause other unpredictable problems.

Hi Weihnachtsbar;

The code just posted only “almost works”. |-)

Run it with a value of 2b for #ALPHA, where b = blank.

It will pass the IF test, but if you add 1 to #NUM it will be 21, not three. Of course there is the question of how you want 2b to be interpreted (2 or 20).

A mask of NN would be a better test.

The IS test basically tests to see if a variable can be “converted” to that format. For example, you can COMPUTE #NUM = VAL (#ALPHA) . Then an add of 1 to #NUM will result in an answer of 3, not 21.

steve

Well, sir, I am sure we could edit MONEY fields every time we read records from a file. We currently use File Handlers for many of our files and the code could be placed in these type of subprograms.

I was hoping to avoid the OVERHEAD with a Compiler option that would force an abend … c’est la vie …

The original post asked for a complier option for COMPUTE. This is not available.

If the bogus values are coming from a WORK file, then the SELECT clause of the READ WORK statement should be what you need. It verifies the contents of numeric fields in each record.

Are individual records independent transactions? If so, you probably do not want an Abend. You would want to note that there is a problem with a particular record (e.g. via MASK ) write a problem report, and continue with the next record/transaction.

However, if the entire run is an interdependent set of transactions, you would want an error in one record to cause an abend. Unfortunately, as noted in earlier posts, Natural will do arithmetic with not numeric data. Hence, you are faced with two prospects.

Either do a MASK test and conditionally end the program

Or, use Natural to force an Abend for bad data. I am guessing that you are either using READ WORK FILE RECORD (which does not do data validity checking), or using READ WORK FILE into a single large alpha variable, which is REDEFINEd into fields, some of which are numeric.

If the latter, you might consider using READ WORK FILE with separate fields. Now this would lead to a performance “hit”. You could minimize this by something like:

                    define data local
                    1 alpha1 (a70)
                    1 redefine alpha1
                       2 first-alpha (a12)
                       2 second-alpha (a22)
                       etc
                    1 first-dollar-field (n8.2)
                    etc

READ WORK FILE alpha1 first-dollar-field alpha2 second-dollar-field etc

So the only fields that are being isolated are the ones that require checking. all other fields would be incorporated in longer alpha strings.

steve

Steve, you are right. I checked with the programmer and the input was a Work file.

Now that we have changed the MOVE ‘numeric’ compiler option to version2.2, it should be impossible to get non-numeric data on to a Natural database file as long as we are moving elementary items - good coding practice.

My mind rests easier. Thanks.