Sum of Double numbers in a list giving weird results

Viewed 27

We have the following legacy function in our application:

public static Double getSum( List<Double> values ) {
    Double sum = null;
    for( Double value : values ) {
        if ( value != null ) {
            if ( sum == null ) {
                sum = value;
            } else {
                sum += value;
            }
        }
    }

    return sum;
}

I am calling it with main using following snippet :-

public static void main( String[] args ) {
    Double sum = getSum( Arrays.asList( -49.66, -42.02, 42.02, 49.66 ) );
    System.out.println( "Sum=" + sum );
}

It is supposed to give output as 0. But it is giving result as -7.105427357601002E-15. When I tried to debug it, the first two values are being added properly but after adding the third value, a decimal component is getting automatically and result after adding third value is -49.660000000000004. Can anybody please point out why this would happen? We are anyways going to replace it

values.stream().filter( value -> value != null ).mapToDouble( Double::doubleValue ).sum();

But, I still would like to understand the reason behind this discrepancy in the original method

Edit:- I tried the solutions in the mentioned link. I changed my method to use BigDecimal instead of Double. But the same error persists. Updated code:-

 public static BigDecimal getSumBigDecimal( List<BigDecimal> values ) {
    BigDecimal sum = null;
    for( BigDecimal value : values ) {
        if ( value != null ) {
            if ( sum == null ) {
                sum = value;
            } else {
                sum = sum.add( value );
            }
        }
    }
    return sum;
}

Updated main method:-

public static void main( String[] args ) {
    // Double sum = getSum( Arrays.asList( -49.66, -42.02, 42.02, 49.66, 0.11, -0.105 ) );

    BigDecimal sum = getSumBigDecimal(
        Arrays
            .asList( new BigDecimal( -49.66 ), new BigDecimal( -42.02 ), new BigDecimal( 42.02 ), new BigDecimal( 49.66 ), new BigDecimal( 0.11 ), new BigDecimal( -0.105 ) ) );
    System.out.println( "Sum=" + sum );
}

Getting output as 0.00500000000000000444089209850062616169452667236328125000 even with BigDecimal

0 Answers
Related