2009-03-15 12 views
3

プロジェクトオイラーの問題の多くは、かなりの回数の除算チェックが必要なので、私はZX81 BASICでこのタスクを実行する最速の方法を見つけようとしています。ZX81ベーシックでの迅速な除算チェック

これまでのところ私はNDかによって分割可能であるかどうか、チェックするためにINT(N/D)から(N/D)を比較しました。
私はZ80 machine codeでテストを行うことを考えていましたが、マシンコードでBASICの変数を使用する方法をまだ理解していません。

どのように達成できますか?

+0

ZX81 BASICを使用しているのはなぜですか? –

+1

(エミュレートされた)Sinclair ZX81を使ってProject Eulerの問題を解決するための狂った小さなペットプロジェクト – vipirtti

+1

私は地下に2つの実際のZX-81(大容量の16KBメモリモジュールを備えています)それらを取り除く心がなかった! –

答えて

2

RANDOMIZE USRがZX81で利用可能かどうかわかりませんが、アセンブリ内でルーチンを呼び出すために使用できると思います。引数を渡すには、RANDOMIZE USRを実行する前にPOKEを使用して固定メモリの場所を設定する必要があります。

私はROMに実装されているルーチンのリストを見つけてZX Basicをサポートすることを忘れないでください。浮動操作を実行するにはいくつかの方法があります。

浮動小数点の代わりに、固定小数点演算を使用することができます。数学コプロセッサがないような状況では、はるかに高速です。

詳細については、Sinclairユーザーの問題を参照してください。彼らは、ZXスペクトルのプログラミングに関連する記事を公開しました。

0

事前に既知のメモリ位置に値を配置する必要があります。 Z80アセンブラ内の同じ場所を使用します。 2つの間にパラメータを渡すことはありません。

これは、私が(まだ)ZX Spectrum 48のことを覚えていることに基づいています。幸いですが、あなたはhwのアップグレードを検討するかもしれません。 ;/

+0

問題にハードウェアを投げ込むのはどうですか? :-D – vipirtti

4

既存のソリューションで十分です。あなたがプロファイリングのボトルネックになっていると分かったら、それを何か速く置き換えてください。 (もちろん、まじめな顔で言った。)

とにかく、ZX81の上にあなただけのFASTモードに切り替えることができます。

+0

私はFASTモードをよく知っています。残念ながら、10001番目の素数を求めるアルゴリズムを試したところ、FASTモードをオンにしても10時間かかりました。 – vipirtti

+2

さて、ちょうど100台のZX81を手に入れ、RS-232ケーブルで接続してください。こんにちはpresto - スレッドプール! –

+0

@Earwicker:解答についてはわかりませんが、そのコメントのまったく恥ずかしがり屋のためにこれをupvoteする必要があります:-) – vipirtti

0

Z80マシンコードの問題点は、浮動小数点演算(浮動小数点演算はありません。また、整数除算または乗算はありません)です。 Z80アセンブラで独自のFPライブラリを実装することは自明ではありません。もちろん、組み込みのBASICルーチンを使うことができますが、BASICに固執することもできます。

+0

プロジェクトオイラーの問題についての一つの良い点は、浮動小数点が本当に必要ないということです。積分計算はうまくいく。この問題は、数が積分に匹敵するかどうかを調べることによって得られます。 – vipirtti

+0

N/D = INT(N/D)はFPを使用しますか? –

+0

これは、浮動小数点を使用しないものを使用して、テストをより効果的に行う方法があると思われる理由です。 – vipirtti

7

これを機械コードで繰り返し行うことで、非常に高速に実行できます。ようなものになるだろう

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から呼び出すことができます。

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.あなたがそれらに慣れていない場合、これはフラグを説明します:あなたは、おそらくのような何かをしたいと思うので、BCレジスタ・ペアに何でも何USRリターンです。 ZX81に焦点を当てるのではなく、Spectrumであるにもかかわらず、メインのサイトからZ80の良いものへのリンクが増えています。

16ビットバージョンは、レジスタペア操作を使用してもかなり似ています。 16ビットを超える必要がある場合は、少し複雑になるでしょう。

どのようにロードするかはあなた次第ですが、従来の方法ではDATAステートメントとPOKEを使用していました。あなたはアセンブラがあなたのためにマシンコードを理解することを好むかもしれません!

+1

フォローアップとして、これは遅すぎると長い分裂をすることができると付け加えておきますが、もう少し手間がかかります。 – cyborg