1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| (* Compilation
ocamlopt -o root nums.cmxa root_num.ml
*)
let root_num index radicand =
(* parameters *)
let max_iter = 1000000
and epsilon = Num.div_num (Num.Int 1) (Num.Int 1000000) in
(* constants *)
let one = Num.Int 1 in
let one_on_index = Num.div_num one index
and pred_index = Num.sub_num index one
in
(* Newton's methode *)
let rec aux iter acc index radicand =
if iter <= 0
then acc
else begin
(* New estimation *)
let new_acc =
Num.mult_num
one_on_index
(Num.add_num
(Num.mult_num pred_index acc)
(Num.div_num radicand
(Num.power_num acc pred_index)
)
)
in
(* check step *)
let step = Num.abs_num (Num.sub_num acc new_acc) in
if Num.le_num step epsilon
then new_acc
else aux (pred iter) new_acc index radicand
end
in
aux max_iter one index radicand
(* help message *)
let usage () =
Printf.printf "%s index radicand\n Compute the index-th root of radicand and print the result in standart output.\n" Sys.executable_name
(* main *)
let main () =
if Array.length Sys.argv != 3
then usage ()
else
let index = int_of_string Sys.argv.(1)
and radicand = int_of_string Sys.argv.(2)
in
let result =
Num.approx_num_exp 10
(root_num (Num.Int index) (Num.Int radicand))
in
Printf.printf "%s\n" result
let _ = main () |