Big_int 阶乘异常

Big_int factorial exception

我尝试使用 Big_int 实现阶乘,utop 可以对其求值,但它在 运行 时间内失败了。这是代码:

let factorial (num : int) =
  let n = Big_int.big_int_of_int num in
  let rec fac (n : Big_int.big_int) : Big_int.big_int =
  if n = Big_int.zero_big_int then Big_int.unit_big_int
  else Big_int.mult_big_int n (fac (Big_int.sub_big_int n Big_int.unit_big_int)) in
  fac n

如何解决这个问题?使用 Big_int 实现阶乘的正确(和简短)方法是什么?
运行 此代码:阶乘 3;;
错误输出:

Exception: (Invalid_argument "compare: abstract value").
Raised by primitive operation at file "//toplevel//", line 4, characters 5-29
Called from file "//toplevel//", line 5, characters 30-80
Called from file "//toplevel//", line 5, characters 30-80
Called from file "//toplevel//", line 5, characters 30-80
Called from file "toplevel/toploop.ml", line 180, characters 17-56

问题出在这个比较中n = Big_int.zero_big_int。如果您将其更改为使用 Big_int 的函数来比较 big_ints -- eq_big_int,那么一切都应该有效。

这是使用尾递归实现此函数的另一个示例:

open Big_int

let factorial (num : int) : big_int =
  let rec fac_big_int n acc =
    if n = 0 then acc
    else fac_big_int (pred n)
                     (mult_big_int (big_int_of_int n)
                                   acc)
  in
    fac_big_int num unit_big_int

utop中的测试:

μ> #load "nums.cma";;
μ> #use "fact_big_int.ml";;
val factorial : int -> big_int = <fun>
μ> string_of_big_int (factorial 10);;
- : string = "3628800"
μ> string_of_big_int (factorial 30);;
- : string = "265252859812191058636308480000000"