Jump to content
IGNORED

How NOT to use NOT: a CALL KEY() example


OLD CS1

Recommended Posts

Here is an interesting one. In my program I am testing true/false values by just referencing the variable. Any value other than zero is true and a value of zero is false.

 

I changed this subroutine

100 CALL KEY(0,K,S) :: IF S THEN 110 ELSE 150
110 REM PROCESS KEYPRESS
120 REM WORK DONE
130 REM SET A RETURN VARIABLE
140 RETURN
150 REM SOMETHING ELSE IS DONE HERE
160 RETURN

To this

100 CALL KEY(0,K,S) :: IF NOT S THEN 150
110 REM PROCESS KEYPRESS
120 REM WORK DONE130 REM SET A RETURN VARIABLE
140 RETURN
150 REM SOMETHING ELSE IS DONE HERE
160 RETURN

But the results are not what are expected. If a key is pressed in line 100 the jump is still taken to line 150. HOWEVER, separating out CALL KEY() and the IF-THEN like so

100 CALL KEY(0,K,S)
105 IF NOT S THEN 150

does work as expected.

 

What gives??

 

Link to comment
Share on other sites

Okay.... scratch that, maybe..?? NOW the original subroutine works...

 

NOPE, got it to do it again. But apparently the problem is in the remainder of the subroutine. After a failed scan of keyboard unit 1, I then scan keyboard unit 3. When I test for S, interestingly, when S=1, NOT S is -2.

WOAH! I will post up the entire program I am using to test in the next message in a few minutes.

Link to comment
Share on other sites

Here is the full test program with input subroutine. It looks like I will have to go back to testing for true with a THEN fall-through and an ELSE jump-past. Note when it prints S=1 it will be followed on the same line by -2. Only a -1 will give the expected 0. So, the real problem is using the NOT operator: only use it on boolean (0 -1) results and not on anything with a real value. I shall change the subject to reflect.

5 DEF JOY(@)=ABS(((SGN(@)+3)/2)*SGN(@))
6 K$(0)=CHR$(2)&CHR$(3)&CHR$(0)&CHR$(5)&CHR$(18)::
10 P=1 :: GOSUB 100 :: PRINT J:
20 IF J THEN PRINT "DETECTED" ELSE 10
30 GOTO 10
100 J=0 :: IF P<0 THEN 140
110 CALL KEY(P,K,S):: IF NOT S THEN 140
120 J=POS(K$(0),CHR$(K),1):: IF J=0 THEN 150
130 RETURN
140 CALL JOYST(ABS(P),X,Y):: IF X+Y THEN 190
150 CALL KEY(3,K,S):: PRINT "S=";S,NOT S :: IF NOT S THEN 180
160 J=4+POS(K$(1),CHR$(K),1)
170 J=J*-(J>4)
180 RETURN
190 IF SGN(X)AND SGN(Y)THEN 170
200 J=JOY(X)+(JOY(Y)-2*(Y<>0)):: RETURN
  • Like 1
Link to comment
Share on other sites

Yup. The issue is the twos-complement, alluded to in the Extended BASIC manual, p.43:

 

 

The logical operators can also be used directly on numbers. They convert the numbers to
binary notation, perform the designated operation on a bit level, and then convert the result
back to decimal representation.

 

 

Then on the following page shown in specific and precise detail that NOT 1 is exactly -2!

 

In conclusion...

 

post-27864-0-61150600-1519369531.jpg

Link to comment
Share on other sites

Not sure what you mean by the 2s complement, 1 = 00000001 -> bitwise NOT 1 = 11111110 (yes I know in the TI they are 16bits so 000000000000001 and 1111111111111110)

 

The fact the result has also meaning as a signed quantity (a number, -2 in your case) is really immaterial once you step into bitwise operations as for them bits are bits.

I believe the surprise here is that logical operators become bitwise operators automatically when applied to numbers.

  • Like 1
Link to comment
Share on other sites

Since the BASIC interpretator doesn't have any separate data type for booleans, but use the normal floating point format for them too, this is what you get.

When you use logical operators like NOT, AND or OR, the floating point value will be considerd as an integer, the bitwise operation is performed and then the result is once again a floating point number. The operator NOT in BASIC executes the same as INV in assembly, i.e. invert all bits. As already found out above, false is represented by all bits being zero, and that's zero when looking at the value as a number, too. But all bits being one is -1 when using the value as a two-complement number.

Pascal is implemented differently. There, only the least significant bit is evaluated. Now here the data type boolean is normally used, but if you type cast an integer into a boolean, then all odd numbers are true and all even number are false.

Link to comment
Share on other sites

Two’s complement representation has nothing directly to do with logical operators used as bitwise operators. NOT, as a bitwise operator, takes the ones’ complement of the unsigned integer in question, that is, it inverts it, changing every 1-bit to 0 and every 0-bit to 1. Treating 1 as a 16-bit unsigned integer, NOT 1 = NOT 00000000000000012 = 11111111111111102 = 6553410, which just happens to be the two’s complement representation of the signed integer -210 in 16 bits,

 

As an aside, when considering signed numbers, negating a 16-bit integer requires taking its two’s complement, which can be done by first taking its ones’ complement (inverting it) and adding 1, ignoring the overflow. But, I digress...

 

...lee

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...