2016-06-05 1 views
0

Я пытался реализовать факториальное использование Big_int, utop может его оценить, но он не работает во время выполнения. Вот код:Факториальное исключение Big_int

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?
Запустить этот код: factorial 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 
+0

Вычисление факториалов с использованием рекурсии должны быть зарезервированы для обучения упражнений. Правильный способ сделать это будет использовать гамма-функцию и memoization. – duffymo

+0

Что говорит об ошибке? Как вы называете «факториалом»? –

+0

@duffymo Интересно ... Как избежать потери точности при использовании гамма-функции? Или есть способ вычислить его без использования чисел с плавающей запятой? –

ответ

1

Проблема заключается в этом сравнении n = Big_int.zero_big_int. Если вы измените его на использование функции Big_int для сравнения big_int s - 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" 

 Смежные вопросы

  • Нет связанных вопросов^_^