TRUE/FALSE TESTING ================== Testing conditions or switches for TRUE or FALSE can be confusing, so first let's look at some QBasic/QuickBasic (QB) rules: RULE #1: A boolean expression: any expression that evaluates as follows: * to TRUE (nonzero) * to FALSE (zero) RULE #2: Conditional statements like IF, DO...LOOP, WHILE...WEND test a boolean expression and will execute, branch or loop based on whether the boolean expression is TRUE (nonzero) or FALSE (zero). RULE #3: However, when a boolean expression is used as a value, assigned to a variable or output in any way, QB will convert the result, after evaluation, to TRUE (-1) or FALSE (0). EXAMPLES: x=2 if x then print "is true" .....Will print because x is TRUE (nonzero) if x-2 then print "is true" ...Will not print because x-2 is FALSE (zero) if x-5 then print "is true" ...Will print because x-5 is -3 is TRUE (nonzero) result = (x=2) ................result will be -1 (TRUE) because x=2 is true result = (x>0) ................result will be -1 (TRUE) because x>0 is true result = (x<0) ................result will be 0 (FALSE) because x<0 is false EXAMPLE OF TESTING A SWITCH WITH AN IF STATEMENT: if switch then goto switchon The boolean expression containing the variable "switch" is evaluated for zero or non-zero in accordance with Rule #2. * If the result is non-zero, the condition is considered TRUE, and the goto takes place. * If the result is zero, the condition is considered FALSE, and the goto does not take place. Let me stress a point regarding the value of "switch". The above IF would do the goto under many nonzero circumstances, including: * A value of -1 * A value of 1 The fact that the IF works for -1 or 1 tricks some people into thinking that either of these can always be considered as TRUE. It depends, see Rules #2 and #3 above. EXAMPLE OF STRAIGHTLINE VERSUS TRICKY BOOLEAN CODE: Here's a straightforward line of code. If the code is 1 then we want to increment count1 by 1. if code=1 then count1=count1+1 A clever, but confusing alternative is: count1 = count1 - (code1=1) Here's how it works. The boolean expression (code1=1) is evaluated and the result is either TRUE (-1) or FALSE (0), in accordance with Rule #3. * If it's TRUE (-1), count1 will be incremented because -(-1) is +1. * If it's FALSE (0), count1 will not be incremented because -(0) is 0. This kind of cleverness dates back to assembly language where IF-type conditional logic was avoided. With today's languages, you don't need to be so cute. You'll only be confusing yourself or the next programmer doing maintenance. EXAMPLE OF OVER-SIMPLIFYING CODE WITH BOOLEAN EXPRESSIONS: The following is the code I use to determine if a year is leap year. The resultant variable Isleap is set to TRUE (-1) or FALSE (0). IsLeap = (Y MOD 4 = 0 AND Y MOD 100 <> 0) OR (Y MOD 400 = 0) The logic is fairly straightforward following the standard definition of leap year which says: If the year is evenly divisible by 4 and not divisible by 100, or if the year is evenly divisible by 400, then it is a leap year. The code has two boolean expressions enclosed in quotes to comply with the definition. So, if either expression is true, it is a leap year. Here's another implementation of the same logic which at first glance looks a little simpler. Isleap = (Y MOD 4 = 0) - (Y MOD 100 = 0) + (Y MOD 400 = 0) This code, which also works by the way, has three boolean expressions enclosed in quotes. Taking into account that TRUE is -1 and FALSE is 0, arithemetic is performed on the results of these expressions to produce a final TRUE/FALSE condition. It took me a while to understand this code, and I tested it with a little program. I'll let you figure it out. Again, the second version of the code looks simpler, but I consider it more complicated. Like Albert Einstein said: "We have to make things simple, but not simpler." RECOMMENDATIONS: 1) Be aware of Rule #2 when writing conditional statements, that is, TRUE is nonzero and FALSE is zero. 2) If you're going to use or assign the results of boolean expessions, remember that TRUE is -1 and FALSE is 0. 3) If you're going to use switches, avoid using 1 for on, and 0 for off, even if that seems to make more sense to you. Use -1 for on, and 0 for off. The recommended and more explicit way of handling switches is as follows: CONST FALSE = 0 CONST TRUE = NOT(FALSE) ..... this is equal to -1 if somecondition then switch is TRUE if switch = TRUE then goto swon if switch = FALSE then goto swoff To flip a switch, turn it off if on, or turn it on if off: switch = not(switch) *****