
(* This file is part of Numerix.  Numerix is free software; you can
   redistribute it and/or modify it under the terms of the GNU General
   Public License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
   USA *)

    (* +-------------------------------------------------------+
       |  Démonstration de la bibliothèque Numerix avec Ocaml  |
       +-------------------------------------------------------+ *)

(* calcul de (sqrt(3) + sqrt(2))/(sqrt(3)-sqrt(2)) avec n décimales *)
(* M. Quercia, le 31/01/2001 *)

open Numerix

module Main(E:Int_type) = struct
  module I = Infixes(E)
  open E
  open I

  (* version fonctionnelle *)
  let calc_func n =
    let dix_n  = (of_int(5) ** n) << n in   (* 10^n  *)
    let dix_2n = sqr(dix_n)            in   (* 10^2n *)
    let sqrt_2 = sqrt(dix_2n *. 200)   in   (* sqrt(2) avec n+1 décimales *)
    let sqrt_3 = sqrt(dix_2n *. 300)   in   (* sqrt(3) avec n+1 décimales *)
    (dix_n * (sqrt_3 + sqrt_2)) / (sqrt_3 - sqrt_2)

  (* version sur place *)
  let calc_in n =
    let dix_n  = make_ref(of_int 0) in
    let dix_2n = make_ref(of_int 0) in
    let sqrt_2 = make_ref(of_int 0) in
    let sqrt_3 = make_ref(of_int 0) in
    let x      = make_ref(of_int 0) in
    let y      = make_ref(of_int 0) in

    pow_in   dix_n    (of_int 5)  n;        (* dix_n <- 5^n ...      *)
    shl_in   dix_n    ~~dix_n      n;        (*        ... * 2^n      *)
    sqr_in   dix_2n   ~~dix_n;               (* dix_2n <- 10^(2n)     *)
    mul_1_in sqrt_2   ~~dix_2n     200;      (* sqrt_2 <- ...         *)
    sqrt_in  sqrt_2   ~~sqrt_2;              (* .. sqrt(2*10^(2n+2))  *)
    mul_1_in sqrt_3   ~~dix_2n     300;      (* sqrt_3 <- ...         *)
    sqrt_in  sqrt_3   ~~sqrt_3;              (* .. sqrt(3*10^(2n+2))  *)
    add_in   x        ~~sqrt_3     ~~sqrt_2;  (* x <- sqrt_3 + sqrt_2  *)
    sub_in   y        ~~sqrt_3     ~~sqrt_2;  (* y <- sqrt_3 - sqrt_2  *)
    mul_in   x        ~~dix_n      ~~x;       (* x <- trunc(10^n*x ... *)
    quo_in   x        ~~x          ~~y;       (*               ... /y) *)
    copy_out x                              (* résultat              *)

  (* fonction principale *)
  let main arglist =

    let rec parse (n,f) = function
      | []          -> (n,  f)
      | "-test"::s  -> parse (30, calc_func) s
      | "-func"::s  -> parse (n,  calc_func) s
      | "-in"  ::s  -> parse (n,  calc_in)   s
      | "-n"::x::s  -> parse (int_of_string x, f) s
      | _ -> prerr_endline "syntaxe : simple [-e entiers] [-test] [-func|-in] [-n <n>]";
             exit(1)
    in
    let (n,f) = parse (30,calc_func) arglist in
    print_endline(string_of(f n))

end (* Main *)

module S = Numcount.Start(Main)
let _ = S.start()

               
