This is an automated email from the ASF dual-hosted git repository. aherbert pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-statistics.git
commit 66ed91bfcc148bbe12ef555e49b735f619b4cd68 Author: aherbert <aherb...@apache.org> AuthorDate: Fri Jul 30 13:30:33 2021 +0100 Handle overflow in probability computation --- .../distribution/PascalDistribution.java | 29 ++++++++++++++++------ 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/PascalDistribution.java b/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/PascalDistribution.java index 94d385b..55b27ab 100644 --- a/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/PascalDistribution.java +++ b/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/PascalDistribution.java @@ -112,10 +112,16 @@ public class PascalDistribution extends AbstractDiscreteDistribution { // Special case exploiting cancellation. ret = Math.pow(probabilityOfSuccess, numberOfSuccesses); } else { - ret = BinomialCoefficientDouble.value(x + - numberOfSuccesses - 1, numberOfSuccesses - 1) * - Math.pow(probabilityOfSuccess, numberOfSuccesses) * - Math.pow(1.0 - probabilityOfSuccess, x); + final int n = x + numberOfSuccesses - 1; + if (n < 0) { + // overflow + // The binomial coefficient -> inf when n -> inf + ret = 0.0; + } else { + ret = BinomialCoefficientDouble.value(n, numberOfSuccesses - 1) * + Math.pow(probabilityOfSuccess, numberOfSuccesses) * + Math.pow(1.0 - probabilityOfSuccess, x); + } } return ret; } @@ -130,10 +136,17 @@ public class PascalDistribution extends AbstractDiscreteDistribution { // Special case exploiting cancellation. ret = logProbabilityOfSuccess * numberOfSuccesses; } else { - ret = LogBinomialCoefficient.value(x + - numberOfSuccesses - 1, numberOfSuccesses - 1) + - logProbabilityOfSuccess * numberOfSuccesses + - log1mProbabilityOfSuccess * x; + final int n = x + numberOfSuccesses - 1; + if (n < 0) { + // overflow + // The binomial coefficient -> inf when n -> inf + ret = Double.NEGATIVE_INFINITY; + } else { + ret = LogBinomialCoefficient.value(x + + numberOfSuccesses - 1, numberOfSuccesses - 1) + + logProbabilityOfSuccess * numberOfSuccesses + + log1mProbabilityOfSuccess * x; + } } return ret; }