The other day, while blithely working on a program, I discovered that something was amiss. I had made an assumption about a certain Boolean operator, and passed on the information without checking my assumption. As Murphy’s law would have it, the assumption was wrong. Going back to the article in issue two of SYNC, there is a discussion of various tricks with logical operators. For example, to test whether a number is not zero, you could use the following program.
10 INPUT N
20 IF N THEN PRINT "NOT ZERO"
There is no problem here. The expression will only be true if N has a value other than zero. I had assumed that the converse was also true, believing expressions such as
IF NOT N THEN PRINT "THE NUMBER IS ZERO"
would also work. To put it bluntly, they don’t. The reason for this is that NOT can function in two different ways (actually, it always functions in the same way, but has two different applications). When working only with true and false (values of -1 and 0), NOT will always make a true expression false, and make a false expression true. So far, so good. As long as the universe is restricted to the values 0 and -1, there is no problem.
Before going on, try the following on your computer. Ask it to PRINT NOT (0). Then ask it to PRINT NOT (-1). As you can see, this works in the expected manner. Now try PRINT NOT (5). You might expect an answer of 0, since 5 (or any number other than zero) is considered to be true when evaluated logically. But life is not that simple. What NOT actually does is to take each bit in the byte and change it. Ones becomes zeroes, zeroes become ones. Now, if you’ve been trying all this, you’ll have found that any positive number N, when used in PRINT NOT(N) will produce a negative number. This has to do with the way the Sinclair stores numbers. In positive numbers, the highest bit is set to zero. In negative numbers, this bit is set to one. Since NOT changes each bit, it will change the sign of most numbers.
You’ve probably also noticed that PRINT NOT (5) does not produce -5. This, also, is tied in with the way numbers are stored in the Sinclair, and will be discussed in a later issue.
By now, it should be obvious that you can’t test for zero with IF NOT (N) THEN PRINT “THE NUMBER IS ZERO”. If N is 0, NOT (N) will produce a value of -1, making the expression true. In this case, that is what we want. When N is zero, the expression will be true, and the statement “THE NUMBER IS ZERO” will be printed. And if N is -1, there is still no problem, since NOT (-1) will produce 0, making the expression false. But if N is any other number, NOT (N), as we’ve seen, will return a value other than zero or minus one. And, when evaluating the IF…THEN statement, the Sinclair will consider any value other than zero to be true. So IF NOT (N) THEN PRINT “THE NUMBER IS ZERO”, will end up printing the message for any value of N other than minus one.
To sum it up, as long as an expression produces only logical values (0 or -1), you can safely use NOT. Expressions such as IF NOT (A=B) THEN GO TO 10, or IF NOT (X 5 AND Y 8) THEN GO TO 10 are fine. They only deal with logical operators. The value inside the parentheses will be either zero or minus one. But if other integers enter the expression, it’s not safe to use NOT.