1313public class DDSketchHistogram implements Histogram {
1414 private final DDSketch sketch ;
1515 private double sum ;
16+ // We use a compensated sum to avoid accumulating rounding errors.
17+ // See https://en.wikipedia.org/wiki/Kahan_summation_algorithm.
18+ private double sumCompensation ; // Low order bits of sum
19+ private double simpleSum ; // Used to compute right sum for non-finite inputs
1620
1721 public DDSketchHistogram (DDSketch sketch ) {
1822 this .sketch = sketch ;
1923 this .sum = 0 ;
24+ this .simpleSum = 0 ;
25+ this .sumCompensation = 0 ;
2026 }
2127
2228 @ Override
@@ -26,7 +32,15 @@ public double getCount() {
2632
2733 @ Override
2834 public double getSum () {
29- return sum ;
35+ // Better error bounds to add both terms as the final sum
36+ final double tmp = sum + sumCompensation ;
37+ if (Double .isNaN (tmp ) && Double .isInfinite (simpleSum )) {
38+ // If the compensated sum is spuriously NaN from accumulating one or more same-signed infinite
39+ // values, return the correctly-signed infinity stored in simpleSum.
40+ return simpleSum ;
41+ } else {
42+ return tmp ;
43+ }
3044 }
3145
3246 @ Override
@@ -37,13 +51,13 @@ public boolean isEmpty() {
3751 @ Override
3852 public void accept (double value ) {
3953 sketch .accept (value );
40- sum += value ;
54+ updateSum ( value ) ;
4155 }
4256
4357 @ Override
4458 public void accept (double value , double count ) {
4559 sketch .accept (value , count );
46- sum += value * count ;
60+ updateSum ( value * count ) ;
4761 }
4862
4963 @ Override
@@ -112,4 +126,16 @@ public void clear() {
112126 public ByteBuffer serialize () {
113127 return sketch .serialize ();
114128 }
129+
130+ private void updateSum (double value ) {
131+ simpleSum += value ;
132+ sumWithCompensation (value );
133+ }
134+
135+ private void sumWithCompensation (double value ) {
136+ final double tmp = value - sumCompensation ;
137+ final double velvel = sum + tmp ; // Little wolf of rounding error
138+ sumCompensation = (velvel - sum ) - tmp ;
139+ sum = velvel ;
140+ }
115141}
0 commit comments