(* termenul de ordin n al seriei; aici 1/n^2; schimbați pentru alte serii *)
let t n = let nf = float n in 1. /. nf /. nf
(* recurența: S_0 = 0, S_n = t_n + S_{n-1}, pentru n > 0 *)
                            
(* V1: apelurile încep de la n, decrementând; adunăm t(n) la revenire
 * deci ultima adunare va fi cu t(n); ordinea calculelor: t(1) + ... + t(n) *)
let rec sum_dec n = if n <= 0 then 0. else t n +. sum_dec (n-1)

(* V2: decrementând n, dar cu acumulator: suma e actualizată înainte de apel
 * la oprire se returnează valoarea acumulată s
 * ordinea calculelor e t(n) + ... + t(1)
 * funcția auxiliară sum_dec2 are două argumente: suma parțială și indicele
 * sum_dec_a = sum_dec2 0. (rămâne o funcție de un argument, indicele *)
let sum_dec_a =
  let rec sum_dec2 s n = if n <= 0 then s else sum_dec2 (s +. t n) (n-1)
  in sum_dec2 0.

(* V3: cu indice k crescător până la n (constant)
 * termenul t(k) adunat la revenire -> ordinea e t(n) + ... + t(1)
 * funcția auxiliară sum_inc1 folosește argumentul n al lui sum_inc (neschimbat)
 * apel inițial cu k=1: sum_inc n = sum_inc1 1 *)
let sum_inc n =
  let rec sum_inc1 k = if k > n then 0. else t k +. sum_inc1 (k+1)
  in sum_inc1 1

(* V4: cu indice k crescător până la n (constant) și acumulator pentru sumă,
 * termenul t(k) se adaugă înainte de apel; calculul: t(1) + ... + t(n)
 * funcția auxiliară sum_inc2 are două argumente: suma parțială și indicele
 * și folosește argumentul n al lui sum_inc_a (indicele limită, neschimbat)
 * apel inițial cu suma 0 și k=1: sum_inc_a n = sum_inc2 0. 1 *)
let sum_inc_a n =
  let rec sum_inc2 s k = if k > n then s else sum_inc2 (s +. t k) (k+1)
  in sum_inc2 0. 1 

(* De ce apar diferențe la ultimele zecimale? *)
let test1 = sum_dec 100000
let test2 = sum_dec_a 100000
let test3 = sum_inc 100000
let test4 = sum_inc_a 100000

This document was generated using caml2html