Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

COBOL IF condition 2

Status
Not open for further replies.

RPBS

Programmer
Aug 30, 2016
1
IN
Belwo is the conditiion.

WS-var.

var1 pic 9(3)
var2 pic 9(6) value '999991', '999992'.
var3 pic x(10)


Condition.

if var1 > 0 and var2 Not = 999991 or 999992

move var3 to out-var

end-if

Data is present to satisfy the IF condition. But this code is not checking the second condition after AND.

So I split the code as below.

IF var1 > 0
IF var2 NOT = '999991'
IF var2 NOT = '999992'
MOVE var2 TO out-var
END-IF
END-IF
END-IF


. Can someone tell me what is the issue here and help me to simplfy this code?
 
Hi,

Code:
if var1 > 0 and (var2 Not = 999991 or var2 Not = 999992)

Skip,
[sub]
[glasses]Just traded in my OLD subtlety...
for a NUance![tongue][/sub]
 
BPRS, welcome to Tek-Tips.

Looking first at this condition:
Code:
if var1 > 0 and var2 Not = 999991 or 999992

This statement is not the equivalent of your nested IF statements. You are using a feature of COBOL that is not available in many other languages: abbreviated combined condition, in your case the variant where both the subject and logical operator are omitted. The final or in your statement has an implied subject (var2) as well as an implied relational operator (NOT EQUAL). So, by making the implied subject and relational operator explicit we have:
Code:
if var1 > 0 and var2 Not = 999991 or var2 not = 999992
Next, you must consider the operator precedence of AND and OR. The rules of COBOL (and most - but not all - other programming languages) evaluate the AND first, followed by the OR. So, the truth value of var1 > 0 and var2 Not = 999991 is evaluated first. If, and only if, this truth value is FALSE is the truth value of var2 not = 999992 evaluated.

My guess is that you really wanted the expression that SkipVought provided, but his expression is not the same as yours.

Your original expression could be stated in an English compound sentence as follows:

If var2 is not equal 999992, then do it, otherwise if var2 is not equal 999991 and var1 is greater than zero, then do it; otherwise, do not do it. In code:
Code:
IF var2 not equal 999992
OR (var2 not equal 999991 and var1 greater than 0)
...
END-IF

Abbreviated combined condition is a novel and useful feature of COBOL in helping make some complex evaluations more readable, but it is also a trap for the unwary. In your use, I think you were imputing operator precedence to the use of the abbreviated feature, but the abbreviated notation only dictates what the equivalent unabbreviated condition is, before the application of operator precedence.

Tom Morrison
Hill Country Software
 
Interesting,

so in short the correct short notation for this should rather be

[tt]if var1 > 0 and (var2 Not = 999991 or 999992)[/tt]

I'd rather prefer the explicit version of Skip, but after your explanation of the feature this would be shorthand for that, but you can't make it shorter without letting it behave different, eg you can't expect COBOL to know you want OR to have precedence over AND this time. In natural language you can do that by stressing out what has precedence, but code precedence is a defined order like mathematical BEMDAS. So the simple solution is likewise when you want addition to occur before multiplication, you use brackets, as they have highest precedence.

Notice OR and AND operators also often are noted as a + and X with a circle around them, though sometimes a + in a circle rather means exclusive OR. Anyway it's pointing towards the same precedence rules you know from basic mathematical operations.

Bye, Olaf.
 
Hi, Olaf.

I would contend that we still do not know the OP's intent, as his original statement and his supplied nested-IF equivalent are contradictory.

From decades in the COBOL compiler business, I can state that abbreviated combined condition is one of the most often misunderstood 'pure' language features, simply due to the fact that its users do not understand the fact that the omitted subject and relational operator are imputed into the lexical stream before syntax analysis. The old COBOL compiler compliance tests (FIPS tests) did test abbreviated combined condition very thoroughly, and many of the tests were amazingly obscure.

My general recommendation if you use abbreviated combined conditions is:[ul]
[li]do not mix AND and OR,[/li]
[li]do not mix in NOT if you are abbreviating the relational operator, and[/li]
[li]use lots of whitespace to create a visual presentation that really matches the actual syntactical result.[/li]
[/ul]

Tom Morrison
Hill Country Software
 
Another option would be to add an 88 level to var2.


[pre]01 VAR1 PIC 9(3) VALUE ZEROES.
01 VAR2 PIC 9(6) VALUE ZEROES.
88 VAR2OK VALUE 999991, 999992.
01 VAR3 PIC X(10) VALUE SPACES.

IF VAR1 > 0 AND NOT VAR2OK
MOVE VAR2 TO OUT-VAR.[/pre]

Randy
 
Randy, your example of using a condition-item matches Olaf's example, but not the OP's nested IF. And the OP seems to have disappeared, so we cannot resolve it.

FWIW, I too would recommend using a condition-item if it promotes readability. But, again from decades in the business, condition-item is an underutilized feature of COBOL. Programmers, for whatever reason, seem to prefer sprinkling 'magic values' as literals throughout the PROCEDURE DIVISION.

Tom Morrison
Hill Country Software
 
IMHO, for the code readability it's better to write it in two IFs with very simple conditions, like:

Code:
if var1 > 0 
  if var2 = 999991 or 999992
*    pass
     continue
  else
     move var3 to out-var
  end-if
end-if

than to try express it in one more complicated condition, like:

Code:
if var1 > 0 and var2 not = 999991 and var2 not = 999992
   move var3 to out-var
end-if
 
Mikrom, I would generally agree, except for the fact that 999991 and 999992 are what I call 'magic values'. To the maintenance programmer, these values may simply be nonsense. Researching the meaning of 999991 and 999992 takes time.

So, as Randy suggests, my preference is to assign an 88-level condition-name to these values. A well constructed condition-name promotes readability and eliminates 'magic values' in the procedure division.

In addition, if either of the two values indicates a single condition, create another condition-name describing that condition. Listing a series of values as shown by Randy allows the compiler to do the OR operation for you - reducing complexity and improving readability.

So, if I use this framework, I judge Randy's IF to be more readable and maintainable than your nested IF.

And, lest this thread devolve into nitpicking on this issue, let us realize the OP has disappeared without a trace, and this thread should come to an end! [bigsmile]

Tom Morrison
Hill Country Software
 
I remember getting into a mini-argument with a remote coworker from Finance. He was trying to write a query to select product codes A and B. So, he wrote the query that way. I tried several times to explain to him that his query must say Product A OR Product B. But he insisted he wanted his results to include Product A AND Product B. We discussed this for about 15 minutes and I was getting exasperated. I finally told him. CHANGE YOUR 'AND' TO AN 'OR' AND YOU WILL GET THE RESULTS YOU WANT. I'M NOT GOING TO TRY TO EXPLAIN BOOLEAN LOGIC OVER THE PHONE! (and yes, I was shouting) [wink]

==================================
advanced cognitive capabilities and other marketing buzzwords explained with sarcastic simplicity


 
It is simple you use and if you want both conditions met and you use or if you want either condition met.

Cretin
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top