Как имитировать логический XOR в ZX Spectrum basic?

Иногда при кодировании в ZX Spectrum Basic мне нужно оценивать логические выражения, которые образованы двумя операндами и логическим xor следующим образом:

IF (left operand) xor (right operand) THEN

Так как ZX Basic знает только NOT, OR и AND, я должен прибегнуть к некоторому необычному вычислению, которое включает многократное использование левых / правых операндов. Это неудобно, так как требует много времени и памяти, и то и другое редко, если вы работаете на 8-битной машине. Интересно, есть ли хитрый трюк для имитации оператора xor.

Чтобы проверить результат, я приведу небольшой пример кода:

 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

Можете ли вы помочь мне найти эффективное решение? Пока я пытался DEF FN x(a,b)=(a AND NOT b) OR (b AND NOT a) но это несколько неуклюже

Редактировать:

Если вы хотите проверить свою идею, я предлагаю эмулятор BasinC v1.69 ZX (только для Windows).

Как отметил @Jeff, большинство Основ, таких как ZX, рассматривают нулевые значения как ложные, а ненулевые - как истинные.

Я адаптировал образец для тестирования с различными ненулевыми значениями.

4 ответа

Решение
DEF FN x(a,b)=((NOT a) <> (NOT b))

С помощью NOT как приведение к логическому значению.

РЕДАКТИРОВАТЬ Ранее каждая сторона была с NOT NOT что не нужно для установления различий между ними, так как один все еще будет принуждать!

РЕДАКТИРОВАТЬ 2 Добавлены парены, чтобы разобраться в проблеме приоритета

Логический xor семантически эквивалентен не равному.

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

должно сработать.

Изменить: В случае целочисленных операндов вы можете использовать

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

Учитывая очень интересный и увлекательный вопрос и ответы здесь, я хотел бы поделиться результатами некоторых тестов производительности (выполненных на эмуляторе):

истекшее время в секундах, лучше меньше. x1 test только чтобы увидеть, соответствует ли выражение требованиям и включает ли распечатку результатов, x256 повторить тот же тест 256 раз, не печатая вывод; without FN тесты такие же, но без учета выражения в выражении FN.

Я также делюсь https://github.com/rondinif/XOR-in-ZX-Spectrum-basic для всех фанатов ретро-вычислений (как и я) и делюсь своими мнениями

Имейте в виду, что значения являются целыми числами: я думаю, что математическая операция может быть забавной: (AB)*(AB) должна работать. Она должна быть менее трудоемкой, основываясь на простой операции.

Или с ABS: ABS (AB)

Другие вопросы по тегам