As Pad wrote, this is apparently a Taylor expansion of cos (x) around x = 0:
cosine (x) = 1 - xΒ² / 2! + xβ΄ / 4! - xβΆ / 6! + ...
So your question is XY: you presented a solution, not a problem. Presenting the problem instead simplifies solving it in different ways.
Let's start by writing a float specific version in F #:
let cosine nx = let rec loop iqtc = if i=n then c else loop (i + 1) (q + 10 + 8*i) (-t * x * x / float q) (c + t) loop 0 2 1.0 0.0
For example, we can calculate 1M expansion terms x = 0.1:
cosine 1000000 0.1
The best way to make this polymorphism in F # is to parameterize the function over the operators it uses and mark it as inline to remove the performance overhead of this parameterization:
let inline cosine zero one ofInt ( ~-. ) ( +. ) ( *. ) ( /. ) nx = let rec loop iqtc = if i=n then c else loop (i + 1) (q + 10 + 8*i) (-.t *. x *. x /. ofInt q) (c +. t) loop 0 2 one zero
Now we can evaluate 1M expressions using a float like this, it is as fast as before:
cosine 0.0 1.0 float ( ~- ) (+) (*) (/) 1000000 0.1
But we can also do single precision float :
cosine 0.0f 1.0f float32 ( ~- ) (+) (*) (/) 1000000 0.1f
And the rationality of arbitrary accuracy:
cosine 0N 1N BigNum.FromInt (~-) (+) (*) (/) 10 (1N / 10N)
And even symbolic:
type Expr = | Int of int | Var of string | Add of Expr * Expr | Mul of Expr * Expr | Pow of Expr * Expr static member (~-) f = Mul(Int -1, f) static member (+) (f, g) = Add(f, g) static member (*) (f, g) = Mul(f, g) static member (/) (f, g) = Mul(f, Pow(g, Int -1)) cosine (Int 0) (Int 1) Int (~-) (+) (*) (/) 3 (Var "x")
To make this faster, raise the common -x*x subexpression from loop .