を返し、これは、整数オーバーフローです。ペリン番号6443は大きすぎるので標準のOCaml表現には適合しません。 int64型に切り替えることができますが、すぐに最大値に達するでしょう。任意の長さのペリン数を計算する場合は、任意の大きな数値を提供するライブラリ(例えば、Zarith)に切り替える必要があります。ここで
は(Zarithライブラリを使用して)の任意精度数値を使用してペラン数字を計算し、同じアルゴリズムの例である:
# #install_printer Z.pp_print;;
# perrin 6443;;
- : Z.t =
6937727487481534145345362428447384488478299624972546803624695551910667531554047522814387413304226129434527926499509496229770899828053746244703038130158033495659756925642507460705324476565619563726313143585381473818236243926914534542432440183345586679670347146768666345957457035004600496858722149019370892348066080092386227405747647480490430105430719428536606680584617305233160609609912020683184996768739606851007812320606992975981778299643926692143069608878875765580902743031572791438636355138605019665803104979890697923714757674707178907100143056837109943637042907642787339851137110850937972239227931113199614637067827389939915715964263895232644082473556841869600234790536494644702234455771939854947229042244627157330814752633389708917381476591438570001576028511405244641287078061574227
#
あなたが気づくことがあります。
let ftp = Hashtbl.create 1
let (+) = Z.add
let rec perrin n =
match n with
| 0 -> Z.of_int 3
| 1 -> Z.of_int 0
| 2 -> Z.of_int 2
|_ -> if Hashtbl.mem ftp n
then Hashtbl.find ftp n
else
begin
Hashtbl.add ftp n (perrin (n-2) + perrin (n-3));
Hashtbl.find ftp n
end
そして、ここでは結果がありますその数は確かに非常に大きく、32ビットまたは64ビットに適合する機会はありません。あなたは、あなたがOCamlは、任意の精度の数値のためのBig_int
モジュールを組み込み使用することができ、zarith
ライブラリをインストールすると、余分な依存関係を追加したくない場合は
# Z.numbits (perrin 6443);;
- : int = 2614
:実際には、2614ビットを必要とします。 Big_int
モジュールに基づく実装は次のとおりです。
open Big_int
let ftp = Hashtbl.create 1
let (+) = add_big_int
let rec perrin n =
match n with
| 0 -> big_int_of_int 3
| 1 -> big_int_of_int 0
| 2 -> big_int_of_int 2
|_ -> if Hashtbl.mem ftp n
then Hashtbl.find ftp n
else
begin
Hashtbl.add ftp n (perrin (n-2) + perrin (n-3));
Hashtbl.find ftp n
end;;
出典
2016-10-26 21:06:00
ivg
このコードはどのように実装されていますか? –
これを実装する必要はありません。既に実装されています。記事のリンクを参照してください。インストールする必要があります(例えば 'opam install zarith'や' sudo apt-get install libzarith-ocaml-dev'など)、トップレベルで '#use" topfind ";; #require "zarith" ;; 'コンパイルするには 'ocamlbuild'を使い、' -pkg zarith'オプションを渡します。 – ivg
実際には、インストールを混乱させたくない場合は、zarithではなく、組み込みの 'big_int'モジュールを使用することができます。私は 'big_int'を使う例で更新しました。余分な作業をしなくてもすぐに動作するはずです。 – ivg