Я рекомендую найти рекуррентное соотношение для коэффициентов полинома Лагерра:
C(k+1) = g(k)C(k)
g(k) = C(k+1) / C(k)
g(k) = -z * (j - k) / ((j - i + k + 1) * (k + 1)) //Verify this yourself :)
Это позволяет вам избежать большинства факториалов при вычислении полинома.
После этого я буду следовать Идея Северина выполнять вычисления в логарифмах, чтобы не перегружать двойной диапазон с плавающей запятой:
log(F) = log(sqrt(i!/j!)) - |z|^2 + (j-i) * log(-z) + log(L(|z|^2))
log(L) = log((2*j - i)!) + log(sum) // where the summation is computed using the recurrence relation above
и использовать тот факт, что:
log(a!) = sum(k=1..a, log(k))
, а также:
log(z) = log(|z|) + I * arg(z) for complex z
log(-z) = log(|z|) + I * arg(-z)
log(-z) = log(|z|) - I * arg(z)
для части log(sqrt(i!/j!))
, которую я бы сделал (предполагая, что j> = i):
log(sqrt(i!/j!))
= 0.5 * (log(i!) - log(j!))
= -0.5 * sum(k==i+1..j, log(k))
Я не пробовал это, так что определенно могут быть небольшие ошибки здесь и там. Этот ответ больше о технике, а не о готовности к копированию