Dart
Dart copied to clipboard
Bug in factorial calculation
Factorial of a negative number does not exist Factorial of a real number does not exist
As mentioned earlier, the traditional definition of the factorial function is only valid for non-negative integers, so it does not make sense to compute the factorial of negative or real numbers in the same way. However, here is an implementation of the gamma function and the signed factorial that can handle negative and real numbers
import 'dart:math';
double gamma(double x) {
const double pi = 3.141592653589793;
if (x < 0.5) {
return pi / (sin(pi * x) * gamma(1 - x));
}
x -= 1;
double a = 0.99999999999980993;
const List<double> p = [
676.5203681218851, -1259.1392167224028, 771.32342877765313,
-176.61502916214059, 12.507343278686905, -0.13857109526572012,
9.9843695780195716e-6, 1.5056327351493116e-7
];
for (int i = 0; i < p.length; i++) {
a += p[i] / (x + i + 1);
}
double t = x + p.length - 0.5;
return sqrt(2 * pi) * pow(t, x + 0.5) * exp(-t) * a;
}
double factorial(num n) {
if (n is int) {
assert(n >= 0, "Factorial of a negative number does not exist");
}
return gamma(n + 1);
}
double signedFactorial(int n) {
if (n % 2 == 0) {
return factorial(n);
} else {
return -factorial(n);
}
}
The gamma function uses the Lanczos approximation to compute the gamma function, which is a well-known way to compute the gamma function for real and complex numbers. The factorial function simply computes gamma(n+1), while the signedFactorial function computes the signed factorial using the definition mentioned earlier. Note that the factorial function also checks that n is non-negative if it is an integer.
import 'dart:math'; double gamma(double x) { const double pi = 3.141592653589793; if (x < 0.5) { return pi / (sin(pi * x) * gamma(1 - x)); } x -= 1; double a = 0.99999999999980993; const List<double> p = [ 676.5203681218851, -1259.1392167224028, 771.32342877765313, -176.61502916214059, 12.507343278686905, -0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7 ]; for (int i = 0; i < p.length; i++) { a += p[i] / (x + i + 1); } double t = x + p.length - 0.5; return sqrt(2 * pi) * pow(t, x + 0.5) * exp(-t) * a; } double factorial(num n) { if (n is int) { assert(n >= 0, "Factorial of a negative number does not exist"); } return gamma(n + 1); } double signedFactorial(int n) { if (n % 2 == 0) { return factorial(n); } else { return -factorial(n); } }
The gamma function uses the Lanczos approximation to compute the gamma function, which is a well-known way to compute the gamma function for real and complex numbers. The factorial function simply computes gamma(n+1), while the signedFactorial function computes the signed factorial using the definition mentioned earlier. Note that the factorial function also checks that n is non-negative if it is an integer.
if this solution is right please assign me and merge my code.
HI @Preetiraj3697
I would suggest you make a PR for the same. I think instead of fixing the existing factorial. why not create a new file for the Lanczos approximation
Ok @akashgk I make a PR.
HI @Preetiraj3697
I would suggest you make a PR for the same. I think instead of fixing the existing factorial. why not create a new file for the Lanczos approximation
@akashgk please merge my code.