Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mimic logical XOR in ZX Spectrum basic?

Sometimes when coding in ZX Spectrum Basic I need to evaluate logical expressions that are formed by two operands and a logical xor like this:

IF (left operand) xor (right operand) THEN

Since ZX Basic does only know NOT, OR and AND I have to resort to some sort of fancy calculation which includes multiple uses of left/right operands. This is awkward since it consumes time and memory, both sparse if you're working on an 8-bit machine. I wonder if there's a neat trick to mimic the xor operator.

To test the outcome I provide a small code sample:

 5 DEF FN x(a,b)=(a ??? b) : REM the xor formula, change here
10 FOR a=-1 TO 1 : REM left operand
20 FOR b=-1 TO 1 : REM right operand
30 LET r=FN x(a,b) : REM compute xor
40 PRINT "a:";a;" b:";b;" => ";r
50 NEXT b
60 NEXT a

Can you help me find a performant solution? So far I tried DEF FN x(a,b)=(a AND NOT b) OR (b AND NOT a) but it's somewhat clumsy.

Edit:

If you want to test your idea I suggest the BasinC v1.69 ZX emulator (Windows only).

As @Jeff pointed out most Basics, such as ZX one's, do consider zero values as false and non-zero ones as true.

I have adapted the sample to test with a variety of non-zero values.

like image 572
yacc Avatar asked Sep 07 '17 13:09

yacc


2 Answers

The logical xor is semantically equivalent to not equal.

IF (left operand) <> (right operand) THEN

should work.

Edit: In the case of integer operands you can use

IF ((left operand) <> 0) <> ((right operand) <> 0) THEN
like image 113
clemens Avatar answered Sep 17 '22 15:09

clemens


DEF FN x(a,b)=((NOT a) <> (NOT b))

Using NOT as coercion to a boolean value.

EDIT Previously had each side with NOT NOT which is unnecessary for establishing difference between the two, as one will still coerce!

EDIT 2 Added parens to sort out precedence issue.

like image 40
Ed. Avatar answered Sep 19 '22 15:09

Ed.