Как имитировать логический 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)