test/java/util/stream/TestDoubleSumAverage.java

Print this page

        

@@ -25,26 +25,36 @@
 import java.util.function.*;
 import java.util.stream.*;
 
 /*
  * @test
- * @bug 8006572
+ * @bug 8006572 8030212
  * @summary Test for use of non-naive summation in stream-related sum and average operations.
  */
 public class TestDoubleSumAverage {
     public static void main(String... args) {
         int failures = 0;
 
-        failures += testForCompenstation();
         failures += testZeroAverageOfNonEmptyStream();
+        failures += testForCompenstation();
+        failures += testInfiniteSum();
 
         if (failures > 0) {
             throw new RuntimeException("Found " + failures + " numerical failure(s).");
         }
     }
 
     /**
+     * Test to verify that a non-empty stream with a zero average is non-empty.
+     */
+    private static int testZeroAverageOfNonEmptyStream() {
+        Supplier<DoubleStream> ds = () -> DoubleStream.iterate(0.0, e -> 0.0).limit(10);
+
+        return  compareUlpDifference(0.0, ds.get().average().getAsDouble(), 0);
+    }
+
+    /**
      * Compute the sum and average of a sequence of double values in
      * various ways and report an error if naive summation is used.
      */
     private static int testForCompenstation() {
         int failures = 0;

@@ -81,23 +91,64 @@
         failures += compareUlpDifference(expectedAvg,
                                          ds.get().boxed().collect(Collectors.averagingDouble(d -> d)),3);
         return failures;
     }
 
-    /**
-     * Test to verify that a non-empty stream with a zero average is non-empty.
-     */
-    private static int testZeroAverageOfNonEmptyStream() {
-        Supplier<DoubleStream> ds = () -> DoubleStream.iterate(0.0, e -> 0.0).limit(10);
+    private static int testInfiniteSum() {
+        int failures = 0;
 
-        return  compareUlpDifference(0.0, ds.get().average().getAsDouble(), 0);
+        List<Supplier<DoubleStream>> dss = new ArrayList<>();
+        dss.add(() -> DoubleStream.of(1.0d, Double.POSITIVE_INFINITY, 1.0d));
+        dss.add(() -> DoubleStream.of(1.0d, Double.NEGATIVE_INFINITY, 1.0d));
+        dss.add(() -> DoubleStream.of(1.0d, Double.NaN, 1.0d));
+        dss.add(() -> DoubleStream.of(1.0d, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 1.0d));
+                          
+        double[] expected = {Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NaN, Double.NaN};
+
+        int i = 0;
+        for(Supplier<DoubleStream> ds : dss) {
+            
+            DoubleSummaryStatistics stats = ds.get().collect(DoubleSummaryStatistics::new,
+                                                             DoubleSummaryStatistics::accept,
+                                                             DoubleSummaryStatistics::combine);
+            System.err.println(i);
+            System.err.println("\ta");
+            failures += compareUlpDifference(expected[i], stats.getSum(), 0);
+            System.err.println("\tb");
+            failures += compareUlpDifference(expected[i], stats.getAverage(), 0);
+
+            System.err.println("\tc");
+            failures += compareUlpDifference(expected[i], ds.get().sum(), 0);
+            System.err.println("\td");
+            failures += compareUlpDifference(expected[i], ds.get().average().getAsDouble(), 0);
+
+            System.err.println("\te");
+            failures += compareUlpDifference(expected[i], ds.get().boxed().collect(Collectors.summingDouble(d -> d)), 0);
+            System.err.println("\tf");
+            failures += compareUlpDifference(expected[i], ds.get().boxed().collect(Collectors.averagingDouble(d -> d)), 0);
+
+            i++;
+        }
+
+        return failures;
     }
 
     /**
      * Compute the ulp difference of two double values and compare against an error threshold.
      */
     private static int compareUlpDifference(double expected, double computed, double threshold) {
+        if (!Double.isFinite(expected)) {
+            // Handle NaN and infinity cases
+            if (Double.compare(expected, computed) == 0)
+                return 0;
+            else {
+            System.err.printf("Unexpected sum, %g rather than %g.%n",
+                              computed, expected);
+                return 1;
+            }
+        }
+
         double ulpDifference = Math.abs(expected - computed) / Math.ulp(expected);
 
         if (ulpDifference > threshold) {
             System.err.printf("Numerical summation error too large, %g ulps rather than %g.%n",
                               ulpDifference, threshold);