如何在ZX Spectrum basic中模仿逻辑XOR?

yac*_*acc 13 basic zxspectrum xor retro-computing

有时在ZX Spectrum Basic中进行编码时,我需要评估由两个操作数和逻辑xor形成的逻辑表达式,如下所示:

IF (left operand) xor (right operand) THEN
Run Code Online (Sandbox Code Playgroud)

由于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
Run Code Online (Sandbox Code Playgroud)

你能帮我找一个高性能的解决方案吗?到目前为止,我尝试过,DEF FN x(a,b)=(a AND NOT b) OR (b AND NOT a)但它有点笨拙.

编辑:

如果你想测试你的想法,我建议使用BasinC v1.69 ZX仿真器(仅限Windows).

正如@Jeff所指出的那样,大多数基础知识,比如ZX one,确实将零值视为,非零值则视为.

我已经调整了样本以测试各种非零值.

cle*_*ens 10

逻辑xor在语义上等同于不相等.

IF (left operand) <> (right operand) THEN
Run Code Online (Sandbox Code Playgroud)

应该管用.

编辑:在整数操作数的情况下,您可以使用

IF ((left operand) <> 0) <> ((right operand) <> 0) THEN
Run Code Online (Sandbox Code Playgroud)

  • 大多数 BASIC 似乎认为零为假,非零为真。鉴于此,我不确定您为什么将 `-1 XOR 1` 视为“边缘情况”。 (3认同)

Ed.*_*Ed. 5

DEF FN x(a,b)=((NOT a) <> (NOT b))
Run Code Online (Sandbox Code Playgroud)

使用NOT作为强制为布尔值。

编辑以前,每一方NOT NOT都不需要建立两者之间的差异,因为仍然会强制!

编辑 2添加括号以解决优先级问题。

  • 抱歉,我已经afk 一段时间了。到目前为止,我可以从您的答案中得出的最短版本是:`DEF FN x(a,b)=(NOT a) &lt;&gt; NOT b`。 (2认同)

Fra*_*ini 5

考虑到这个问题和这里的答案非常有趣和有趣,我想分享一些性能测试的结果(在模拟器上执行): 在此处输入图片说明

经过的时间以秒为单位,越少越好。的x1 test是只看到如果表达式满足要求,并包括结果的打印输出时,x256重复同样的测试256times而不打印任何输出; 该without FN测试是相同的,但没有在FN声明融通表达。

我还在github 上分享代码和测试套件:https://github.com/rondinif/XOR-in-ZX-Spectrum-basic以造福所有复古计算狂热分子(..像我)并分享我们的意见