Recursion Ocaml中的递归-输出意外结果

Recursion Ocaml中的递归-输出意外结果,recursion,ocaml,Recursion,Ocaml,该函数适用于小数字。但是对于大数字,结果中开始返回负数。有人知道怎么解决这个问题吗? 例如: 输出:返回意外结果简而言之,这是因为整数溢出。perrin编号6443太大了,不适合标准的OCaml表示。您可以切换到int64类型,但很快就会达到最大值。如果您想计算任意长度的perrin数,那么您应该切换到提供任意大数的库,例如 以下是同一算法的示例,该算法使用任意精度的数字(使用Zarith库)计算perrin数: 结果如下: let ftp = Hashtbl.create 1 let

该函数适用于小数字。但是对于大数字,结果中开始返回负数。有人知道怎么解决这个问题吗? 例如:


输出:返回意外结果

简而言之,这是因为整数溢出。perrin编号6443太大了,不适合标准的OCaml表示。您可以切换到int64类型,但很快就会达到最大值。如果您想计算任意长度的perrin数,那么您应该切换到提供任意大数的库,例如

以下是同一算法的示例,该算法使用任意精度的数字(使用Zarith库)计算perrin数:

结果如下:

 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位。事实上,它需要2614位:

# #install_printer Z.pp_print;;
# perrin 6443;;
- : Z.t =
6937727487481534145345362428447384488478299624972546803624695551910667531554047522814387413304226129434527926499509496229770899828053746244703038130158033495659756925642507460705324476565619563726313143585381473818236243926914534542432440183345586679670347146768666345957457035004600496858722149019370892348066080092386227405747647480490430105430719428536606680584617305233160609609912020683184996768739606851007812320606992975981778299643926692143069608878875765580902743031572791438636355138605019665803104979890697923714757674707178907100143056837109943637042907642787339851137110850937972239227931113199614637067827389939915715964263895232644082473556841869600234790536494644702234455771939854947229042244627157330814752633389708917381476591438570001576028511405244641287078061574227
# 
如果您不想安装zarith库并添加额外的依赖项,那么可以使用OCaml内置的Big_int模块处理任意精度的数字。以下是基于
Big\u int
模块的实现:

# Z.numbits (perrin 6443);;
- : int = 2614

简而言之,这是因为整数溢出。perrin编号6443太大了,不适合标准的OCaml表示。您可以切换到int64类型,但很快就会达到最大值。如果您想计算任意长度的perrin数,那么您应该切换到提供任意大数的库,例如

以下是同一算法的示例,该算法使用任意精度的数字(使用Zarith库)计算perrin数:

结果如下:

 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位。事实上,它需要2614位:

# #install_printer Z.pp_print;;
# perrin 6443;;
- : Z.t =
6937727487481534145345362428447384488478299624972546803624695551910667531554047522814387413304226129434527926499509496229770899828053746244703038130158033495659756925642507460705324476565619563726313143585381473818236243926914534542432440183345586679670347146768666345957457035004600496858722149019370892348066080092386227405747647480490430105430719428536606680584617305233160609609912020683184996768739606851007812320606992975981778299643926692143069608878875765580902743031572791438636355138605019665803104979890697923714757674707178907100143056837109943637042907642787339851137110850937972239227931113199614637067827389939915715964263895232644082473556841869600234790536494644702234455771939854947229042244627157330814752633389708917381476591438570001576028511405244641287078061574227
# 
如果您不想安装zarith库并添加额外的依赖项,那么可以使用OCaml内置的Big_int模块处理任意精度的数字。以下是基于
Big\u int
模块的实现:

# Z.numbits (perrin 6443);;
- : int = 2614

您不需要实现它,它已经实现了,请参阅文章中的链接。您需要安装它(例如,
opam install zarith
sudo apt get install libzarith ocaml dev
),然后您可以使用
#使用“topfind”在顶层加载它#需要“zarith”。要使用它进行编译,请使用
ocamlbuild
并传递
-pkg zarith
选项。实际上,如果不想干扰安装,可以使用内置的
big_int
模块,而不是zarith。我更新了一个使用
big\u int
的示例。它应该是开箱即用的,不需要额外的工作。为什么要返回呢。在第3行中解除模块Z的绑定时出错。我需要在mac osx上安装Zarith库?是的,如果你想使用Zarith库,你需要安装它,然后加载它。详细信息因操作系统和操作系统配置而异。使用张贴中的第二个示例。它将不会有任何额外的麻烦:)你不需要实现它,它已经实现了,请参阅文章中的链接。您需要安装它(例如,
opam install zarith
sudo apt get install libzarith ocaml dev
),然后您可以使用
#使用“topfind”在顶层加载它#需要“zarith”。要使用它进行编译,请使用
ocamlbuild
并传递
-pkg zarith
选项。实际上,如果不想干扰安装,可以使用内置的
big_int
模块,而不是zarith。我更新了一个使用
big\u int
的示例。它应该是开箱即用的,不需要额外的工作。为什么要返回呢。在第3行中解除模块Z的绑定时出错。我需要在mac osx上安装Zarith库?是的,如果你想使用Zarith库,你需要安装它,然后加载它。详细信息因操作系统和操作系统配置而异。使用张贴中的第二个示例。它将在没有任何额外麻烦的情况下工作:)