How to mimic logical XOR in ZX Spectrum basic?

1k views Asked by At

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.

4

There are 4 answers

5
Ed. On BEST ANSWER
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.

8
clemens On

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
3
Christophe Durieux On

Keep in mind, value are integer: I think mathematical operation could be fun : (A-B)*(A-B) should work It should be less time consuming based on simple operation.

Or with ABS : ABS (A-B)

6
Franco Rondini On

Considering very interesting and fun this question and the answers in here, I would like to share the results of some performance tests (performed on an emulator): enter image description here

elapsed times are in seconds , less is best. the x1 test is only to see if the expression meets the requirements and includes the print out of results, the x256 repeat the same test 256times without printing any output; the without FN tests are the same but without factoring the expression in an FN statement.

I share also the code and test suite on github: https://github.com/rondinif/XOR-in-ZX-Spectrum-basic for the benefit of all retro computing fanatics (..like me) and share our opinions