如何在ZX Spectrum basic中模拟逻辑异或?
How to mimic logical XOR in ZX Spectrum basic?
有时在 ZX Spectrum Basic 中编码时,我需要计算由两个操作数和逻辑异或组成的逻辑表达式,如下所示:
IF (left operand) xor (right operand) THEN
由于 ZX Basic 只知道 NOT、OR 和 AND,因此我不得不求助于某种奇特的计算,其中包括多次使用 left/right 操作数。这很尴尬,因为它会消耗时间和内存,如果你在 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 的,确实将零值视为 false,将非零值视为 true.
我已调整示例以使用各种非零值进行测试。
逻辑异或在语义上等同于不等于。
IF (left operand) <> (right operand) THEN
应该可以。
编辑:对于整数操作数,您可以使用
IF ((left operand) <> 0) <> ((right operand) <> 0) THEN
请记住,值是整数:
我认为数学运算可能很有趣:(A-B)*(A-B) 应该有效
基于简单的操作,它应该更少耗时。
或带 ABS:ABS (A-B)
DEF FN x(a,b)=((NOT a) <> (NOT b))
使用 NOT
作为布尔值的强制转换。
编辑 以前每一方都有 NOT NOT
这对于在两者之间建立差异是不必要的,因为仍然会强制!
编辑 2 添加括号以解决优先级问题。
考虑到这个问题和这里的答案非常有趣和有趣,我想分享一些性能测试的结果(在模拟器上执行):
经过的时间以秒为单位,越少越好。
x1 test
只是看表达式是否符合要求,包括打印结果,x256
重复同样的测试256次,不打印任何输出; without FN
测试是相同的,但没有在 FN 语句中分解表达式。
我也the code and test suite on github: https://github.com/rondinif/XOR-in-ZX-Spectrum-basic为了所有复古计算狂热者(..像我一样)的利益分享我们的观点
有时在 ZX Spectrum Basic 中编码时,我需要计算由两个操作数和逻辑异或组成的逻辑表达式,如下所示:
IF (left operand) xor (right operand) THEN
由于 ZX Basic 只知道 NOT、OR 和 AND,因此我不得不求助于某种奇特的计算,其中包括多次使用 left/right 操作数。这很尴尬,因为它会消耗时间和内存,如果你在 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 的,确实将零值视为 false,将非零值视为 true.
我已调整示例以使用各种非零值进行测试。
逻辑异或在语义上等同于不等于。
IF (left operand) <> (right operand) THEN
应该可以。
编辑:对于整数操作数,您可以使用
IF ((left operand) <> 0) <> ((right operand) <> 0) THEN
请记住,值是整数: 我认为数学运算可能很有趣:(A-B)*(A-B) 应该有效 基于简单的操作,它应该更少耗时。
或带 ABS:ABS (A-B)
DEF FN x(a,b)=((NOT a) <> (NOT b))
使用 NOT
作为布尔值的强制转换。
编辑 以前每一方都有 NOT NOT
这对于在两者之间建立差异是不必要的,因为仍然会强制!
编辑 2 添加括号以解决优先级问题。
考虑到这个问题和这里的答案非常有趣和有趣,我想分享一些性能测试的结果(在模拟器上执行):
经过的时间以秒为单位,越少越好。
x1 test
只是看表达式是否符合要求,包括打印结果,x256
重复同样的测试256次,不打印任何输出; without FN
测试是相同的,但没有在 FN 语句中分解表达式。
我也the code and test suite on github: https://github.com/rondinif/XOR-in-ZX-Spectrum-basic为了所有复古计算狂热者(..像我一样)的利益分享我们的观点