0

My task is to compare two numbers and return true if they are equal by three decimal places. When I print out the value of diff it is 0.0001, but it still doesn't enter the if(diff <= 0.0001) block.

    public class DecimalComparator {
    public static boolean areEqualByThreeDecimalPlaces(double num1, double num2) {
        double diff = Math.abs(num1 - num2);

        System.out.printf("%f", diff);
        if(diff <= 0.0001) {
            return true;
        } else {

            return false;
        }
    }

    public static void main(String[] args) {
        boolean test = areEqualByThreeDecimalPlaces(3.1756, 3.1755);
        System.out.println(test);

        test = areEqualByThreeDecimalPlaces(3.176, 3.175);
        System.out.println(test);
    }
}
    
  • If you write `System.out.println(diff);` instead of `System.out.printf("%f", diff);` you will get `1.0000000000021103E-4` - the value of `diff` is not `0.0001`, you're just not printing its exact value. – kaya3 Mar 27 '21 at 02:20
  • @AbhijitSarkar The question claims that `3.1756 - 3.1755` is equal to `0.0001`, which it is not, because of floating point arithmetic imprecision. The answer you posted yourself does not really make sense in any interpretation of the question. – kaya3 Mar 27 '21 at 02:33

2 Answers2

0

When you need arbitrary precision use BigDecimal. Also, your magic number should be 0.001 for three decimal places. Like,

public static boolean areEqualByThreeDecimalPlaces(double num1, double num2) {
    return new BigDecimal(num1).subtract(new BigDecimal(num2)).abs()
            .compareTo(new BigDecimal(0.001)) <= 0;
}

public static void main(String[] args) {
    System.out.println(areEqualByThreeDecimalPlaces(3.1756, 3.1755));
    System.out.println(areEqualByThreeDecimalPlaces(3.176, 3.175));
}

Outputs

true
false
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
0

While I believe @Elliot Frisch has the best Java approach, it is always difficult to know if one should introduce concepts beyond the standard primitives for what appears to be homework.

In the alternative, knowing that the desired value is 3 decimal places, the problem may be re-conceptualized by multiplying by 1000 and using an int.

Example:

    public static boolean areEqualByThreeDecimalPlaces(double num1, double num2) {
        final int mult = 1000;
        int i1 = (int)(num1 * mult);
        int i2 = (int)(num2 * mult);
        
        return (Math.abs(i1 - i2)) == 0;
    }

The output shows the expected true and false for the test cases.

Just an alternative approach to consider if one cannot switch to using other Java classes.

KevinO
  • 4,303
  • 4
  • 27
  • 36