ALI NEMATH
ALI NEMATH

Reputation: 1

Compare two double values in Java

This is a Java code that should test whether the first three digits after the decimal point are identical. And I need to write this program without a main method.

public class areEqualByThreeDecimalPlaces {
    public static boolean areEqualByThreeDecimalPlaces(double d_1, double d_2) {
        double value_1 = Math.round(1000*d_1);
        double value_2 = Math.round(1000*d_2);

        if (value_1 == value_2) {
            return true;
        } else return false;
    }
}

Input:

(-3.1756, -3.175)

Expected Output:

true

Output received:

false

By using the Math.round it is rounding the value of -3.1756 to -3.176. But I want to check if the three digits after the decimal point are similar.

How do I correct my code?

Upvotes: 0

Views: 2092

Answers (3)

Fabio Scagliola
Fabio Scagliola

Reputation: 472

You could to use ceil instead of round

double value_1 = Math.ceil(d_1 * 1000);
double value_2 = Math.ceil(d_2 * 1000);

EDIT

Thanks to Alex Rudenko's comment, I realized that the correct solution would be using ceil for negative numbers and floor for positive numbers

double value_1 = d_1 < 0 ? Math.ceil(d_1 * 1000) : Math.floor(d_1 * 1000);
double value_2 = d_2 < 0 ? Math.ceil(d_2 * 1000) : Math.floor(d_2 * 1000);

Fabio

Upvotes: 0

Nowhere Man
Nowhere Man

Reputation: 19545

The code to check if the first three digits after the decimal point are identical should just truncate the integer part and keep only the digits in the fractional part by subtracting initial integer part.

Also, it may be needed to use Math.abs or Math.sign to compare the values retrieved from positive and negative inputs:
areEqualByThreeDecimalPlaces(3.1751, -3.1758) == true.

And the last thing: in order to avoid integer overflow for large inputs when multiplying by 1000 it's better to use long.

So the example implementation may look like this:

public static boolean areEqualByThreeDecimalPlaces(double d1, double d2) {
    long value1 = Math.abs((long) (d1 * 1000L) - (long) d1 * 1000L); 
    long value2 = Math.abs((long) (d2 * 1000L) - (long) d2 * 1000L);

    System.out.print(value1 + " == " + value2 + " ? ");
    return value1 == value2;
}

or using a lambda for DoubleToLongFunction:

public static boolean areEqualByThreeDecimalPlaces(double d1, double d2) {
    DoubleToLongFunction f = (d) -> Math.abs((long) (d * 1000L) - (long) d * 1000L);

    return f.applyAsLong(d1) == f.applyAsLong(d2);
}

Tests:

System.out.println(areEqualByThreeDecimalPlaces(-3.175, -3.1752));
System.out.println(areEqualByThreeDecimalPlaces(3.175, 3.1752));
System.out.println(areEqualByThreeDecimalPlaces(3.1751, -3.1758));
System.out.println(areEqualByThreeDecimalPlaces(5_123_456_789.123987, -90_123_456_789.123456));

Output:

175 == 175 ? true
175 == 175 ? true
175 == 175 ? true
123 == 123 ? true

Upvotes: 0

Tom
Tom

Reputation: 11

Going off this code the two values just won't be equal. value_1 = -3176.0 value_2 = -3175.0

If you want to learn a little more about truncating doubles, take a look at this. How can I truncate a double to only two decimal places in Java?

Upvotes: 1

Related Questions