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

Reply via email to