【问题标题】:Quick divisibility check in ZX81 BASICZX81 BASIC 中的快速整除检查
【发布时间】:2009-03-15 12:20:00
【问题描述】:

由于欧拉计划的许多问题都需要您多次进行整除性检查,因此我一直在尝试找出在ZX81BASIC 中执行此任务的最快方法。

到目前为止,我已经比较了 (N/D)INT(N/D) 来检查 N 是否可以被 D 整除。
一直在考虑在Z80 machine code做测试,还没想好如何在机器码中使用BASIC中的变量。

如何实现?

【问题讨论】:

  • 只是出于兴趣,你为什么用ZX81 BASIC ????
  • 只是一个疯狂的小宠物项目,使用(模拟的)Sinclair ZX81 解决 Project Euler 问题:-)
  • 我的地下室里有几台真正的 ZX-81(带有 16KB 大容量内存模块)……我还没忍心摆脱它们!
  • 我的衣柜顶上还有一个 Dragon32(6809 处理器)...

标签: division z80 zx81


【解决方案1】:

您可以通过重复减法在机器代码中快速完成此操作。基本上你有一个像这样的程序:

set accumulator to N
subtract D
if carry flag is set then it is not divisible
if zero flag is set then it is divisible
otherwise repeat subtraction until one of the above occurs

8 位版本类似于:

DIVISIBLE_TEST:
LD B,10
LD A,100

DIVISIBLE_TEST_LOOP:
SUB B
JR C, $END_DIVISIBLE_TEST
JR Z, $END_DIVISIBLE_TEST
JR $DIVISIBLE_TEST_LOOP

END_DIVISIBLE_TEST:
LD B,A
LD C,0
RET

现在,您可以使用 USR 从基本电话呼叫。 USR 返回的是 BC 寄存器对中的任何内容,因此您可能想要执行以下操作:

REM poke the memory addresses with the operands to load the registers
POKE X+1, D
POKE X+3, N
LET r = USR X
IF r = 0 THEN GOTO isdivisible
IF r <> 0 THEN GOTO isnotdivisible

This is an introduction I wrote to Z80 which should help you figure this out. 如果你不熟悉这些标志,这将解释它们。 尽管主要是 Spectrum 而不是 ZX81,但主站点上的 Z80 好东西的链接还有很多。

16 位版本将非常相似,但使用寄存器对操作。如果您需要超过 16 位,它会变得更加复杂。

如何加载它取决于您 - 但传统方法是使用 DATA 语句和 POKE。不过,您可能更喜欢让汇编程序为您找出机器代码!

【讨论】:

  • 作为后续,我可能应该补充一点,如果这太慢,您可以进行长除法,但它有点繁琐。
【解决方案2】:

您现有的解决方案可能已经足够好了。如果您发现它是分析中的瓶颈,请仅将其替换为更快的东西。

(当然是板着脸说。)

无论如何,在 ZX81 上,您只需切换到 FAST 模式即可。

【讨论】:

  • 我非常了解 FAST 模式。不幸的是,当我尝试寻找第 10001 个素数的算法时,即使打开 FAST 模式也需要 10 个小时。
  • 好吧,买一百个 ZX81 用 RS-232 电缆连接起来。嘿 presto - 一个线程池!
  • @Earwicker:不知道答案,但我只需要赞成这个评论的纯粹搞笑:-)
【解决方案3】:

不知道 RANDOMIZE USR 是否在 ZX81 中可用,但我认为它可以用于在汇编中调用例程。要传递参数,您可能需要在执行 RANDOMIZE USR 之前使用 POKE 设置一些固定的内存位置。

我记得在 ROM 中找到了一个支持 ZX Basic 的例程列表。我确定有几个可以执行浮动操作。

浮点的替代方法是使用定点数学。在这种没有数学协处理器的情况下,它的速度要快得多。

您还可以在 Sinclair 用户问题中找到更多信息。他们在 ZX Spectrum 发表了一些与编程相关的文章

【讨论】:

    【解决方案4】:

    您应该首先将值放在一些预先知道的内存位置。然后使用 Z80 汇编器中的相同位置。两者之间没有参数传递。

    这是基于我(仍然)记得的 ZX Spectrum 48。祝你好运,但你可能会考虑升级你的硬件。 ;/

    【讨论】:

    • 现在,将更多硬件投入到问题中的挑战是什么? :-D
    【解决方案5】:

    Z80 机器码的问题在于它没有浮点运算(就此而言,也没有整数除法或乘法)。在 Z80 汇编器中实现您自己的 FP 库并非易事。当然,你可以使用内置的 BASIC 例程,但你也可以坚持使用 BASIC。

    【讨论】:

    • 嗯,关于 Project Euler 问题的一件好事是,您实际上并不需要浮点数。积分计算就可以了。问题在于找出一个数字是否可分为整数。
    • 但是你的 N/D = INT(N/D) 确实使用了 FP,不是吗?
    • 确实如此,这就是为什么我怀疑可能有一种方法可以更有效地进行测试,使用不使用浮点数的东西。
    猜你喜欢
    • 1970-01-01
    • 2011-03-12
    • 2011-03-12
    • 2017-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多