[PATCH] 8178117: Add public state constructors for Int/Long/DoubleSummaryStatistics

Chris Dennis chris.w.dennis at gmail.com
Wed Apr 12 17:08:08 UTC 2017


Something like that was what I was envisioning (of course the inability to represent NaN or infinity with a BigDecimal is annoying). To me this approach really only breaks down when you stop using an actual iteration to perform the computation… as long as a “sum” in some form is part of the internal state then this still works.

> On Apr 12, 2017, at 12:27 PM, Peter Levart <peter.levart at gmail.com> wrote:
> 
> 
> 
> On 04/12/2017 04:41 PM, Peter Levart wrote:
>> On 04/11/2017 10:48 PM, Chris Dennis wrote:
>>> Color me confused… what would the javadoc on the parameter say? It could I guess have an @implNote documenting the meanings of the parameters… but then what use is it? The proposed API simply limits the precision with which a DoubleSummaryStatistic can be copied to be the same as the precision with which it can be “accessed”. That doesn’t seem an enormous problem since I suspect that bulk of usages would be to marshall a “finished” instance and therefore there is no real loss occuring. If we wanted to support arbitrary precision wouldn’t it be better to have a constructor variant that took a BigDecimal, and a matching getPreciseSum() that returned a BigDecimal?
>> 
>> And how would you compute the value for BigDecimal getPreciseSum() so that you could then set 3 internal double fields from BigDecimal without loss of information? 
> 
> 
> ...perhaps we could use the BigDecimal getPreciseSum() together with getSum() to reconstruct the state. For exmaple:
> 
>    /**
>     * Construct an instance with values obtained from another instance.
>     *
>     * @param count what was returned from another instance's {@link #getCount()}
>     * @param sum what was returned from another instance's {@link #getSum()}
>     * @param preciseSum what was returned from another instance's {@link #getPreciseSum()}
>     * @param min what was returned from another instance's {@link #getMin()}
>     * @param max what was returned from another instance's {@link #getMax()}
>     */
>    public DoubleSummaryStatistics(long count,
>                                   double sum, BigDecimal preciseSum,
>                                   double min, double max) {
>        if (count < 0L) {
>            throw new IllegalArgumentException("count < 0");
>        } else if (count > 0L) {
>            if (min > max) {
>                throw new IllegalArgumentException("min > max");
>            }
>            this.count = count;
>            this.min = min;
>            this.max = max;
>            setSum(sum, preciseSum);
>        }
>    }
> 
>    /**
>     * If {@link #getSum()} returns {@link Double#NaN} or {@link Double#POSITIVE_INFINITY}
>     * or {@link Double#NEGATIVE_INFINITY}, then this method returns {@code null},
>     * otherwise it returns a value that is a more precise representation of the
>     * sum of values recorded and can be used in
>     * {@link #DoubleSummaryStatistics(long, double, BigDecimal, double, double)}
>     * to construct an object with internal state that closely resembles the state of
>     * original object.
>     *
>     * @return a precise sum in BigDecimal form.
>     */
>    public final BigDecimal getPreciseSum() {
>        double sum = getSum();
>        if (Double.isNaN(sum) || Double.isInfinite(sum)) {
>            return null;
>        } else {
>            return new BigDecimal(this.sum).add(
>                new BigDecimal(this.sumCompensation));
>        }
>    }
> 
>    private void setSum(double sum, BigDecimal preciseSum) {
>        if (preciseSum == null) {
>            if (!Double.isNaN(sum) && !Double.isInfinite(sum)) {
>                throw new IllegalArgumentException(
>                    "preciseSum is null but sum is not a NaN and not Infinite");
>            }
>            this.sum = this.simpleSum = sum;
>            this.sumCompensation = 0d;
>        } else {
>            if (Double.isNaN(sum) || Double.isInfinite(sum)) {
>                throw new IllegalArgumentException(
>                    "preciseSum is non-null but sum is NaN or Infinite");
>            }
>            this.sum = this.simpleSum = preciseSum.doubleValue();
>            this.sumCompensation = preciseSum.subtract(new BigDecimal(this.sum)).doubleValue();
>        }
>    }
> 
> 
> Hm....
> 
> 
> Regards, Peter
> 



More information about the core-libs-dev mailing list