Удивительно вычислить факториал в FP. Точность числа FP ограничена их мантиссой и на самом деле выше ~ 20 !, вам нужно более 54 бит для хранения (целочисленного) значения, а результат FP является лишь приблизительным и, следовательно, неверный .
Но, если вам нужно только неточное значение в два раза, я бы предложил:
1 / с использованием более простой формулы, такой как формула Стирлинга. https://en.wikipedia.org/wiki/Stirling%27s_approximation#Speed_of_convergence_and_error_estimates
Если вы сохраните 4 или 5 чисел в серии Стирлинга, потеря аппроксимации из-за использования этой формулы не будет больше, чем из-за ограниченной мантиссы. (и это будет намного быстрее).
2 / независимо от того, используете ли вы факториал или Стирлинг, вы можете использовать трюк для увеличения показателя в двойном выражении. Идея просто сохранить показатель ниже 2 ^ 512 и после каждого мульта, вы делаете следующую проверку
int extra_exponent=0;
double theshold = 2^512;
double threshold_inv=2^-512;
....
# check exponent on n
if (n>threshold) {
n *= threshold_inv ; # reduce exponent
extra_exponent++ ; # but keep track of it
}
Вы никогда не переполнитесь, если умножите на число <2 ^ 512. В конце, чтобы получить «реальное» значение, вы должны умножить, но 2 ^ (дополнительно * 512) (что может быть не так просто). И ваша точность ограничена размером мантиссы. </p>
Но лучшее предложение - использовать арифметику с бесконечной точностью. И это единственный способ получить точный результат.