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;
     }

Reply via email to