-3

I have two values and I am trying to compare them, but getting the worng results:

    public void subtotal() throws Exception {
    WebDriverWait wait = new WebDriverWait(session.driver, 100);
    double subtotal_price = 0;
    DecimalFormat decimal = new DecimalFormat("0.00");
    WebElement subtotal = wait.until(ExpectedConditions.visibilityOf( element("Subtotal_cart")));
    Float subtotal_value = Float.parseFloat(subtotal.getText().substring(1));
    logger.info("subtotal_value"+subtotal_value);
    File file = new File("ItemUPC/ItemUPC.txt");
    Scanner sc = new Scanner(file);
    while (sc.hasNextLine()) {
        String[] line = sc.nextLine().split("[|]");
        String price = line[2];
        subtotal_price = subtotal_price + Double.parseDouble(price);
    }
    logger.info("subtotal_price"+subtotal_price);
    if ((subtotal_value)==(subtotal_price))
    {
        logger.info("Subtotals updated");
    }
    else
    {
        logger.info("Subtotals not updated");
    }
}

The following is the ItemUPC file:

2|BATH BENCH|19.00
203|ORANGE BELL|1.78

When I print the value of subtotal_price and Subtotal_value I am getting both as 20.78, but when its getting compared in the if statement, I am getting output as "Subtotals not updated" Not sure where I am getting wrong. Can someone please help? Thank you.

Piku
  • 21
  • 5
  • 1
    @Aaron I don't think that's right. OP is comparing a primitive `double` to an object `Float`, which will get unboxed for the comparison. The issue is the precision, not whether the values are boxed. – Dawood ibn Kareem Aug 31 '20 at 19:25
  • @DawoodibnKareem talking about precision, the result shows to be 20.78 for both. – Piku Aug 31 '20 at 19:30
  • @Piku Neither `double` nor `float` stores decimal numbers exactly in general, so neither value is exactly `20.78`. The reason why this causes you a problem is that you're trying to compare a `double` to a `float`. For decimal arithmetic, I strongly recommend using the `BigDecimal` class, which doesn't have issues with precision. – Dawood ibn Kareem Aug 31 '20 at 19:34
  • @DawoodibnKareem can you please provide me an example? Thanks – Piku Aug 31 '20 at 19:52
  • There are loads of examples online of the use of the `BigDecimal` class. – Dawood ibn Kareem Aug 31 '20 at 19:54
  • Does this answer your question? [What's wrong with using == to compare floats in Java?](https://stackoverflow.com/questions/1088216/whats-wrong-with-using-to-compare-floats-in-java) – Nowhere Man Aug 31 '20 at 20:29

1 Answers1

3

Comparing floating point numbers can be challenging, due to differences in precision between floating point types and their binary representations of decimal numbers.

You have two simple options:

  1. Compare the absolute value of the difference between the two values to an epsilon, or threshold, value
  2. Use BigDecimal as a substitute for your Float and double variable types

Example 1:

// simplification that may fail in certain edge cases
static final double EPSILON = .001; // acceptable error - adjust to suit your needs
if (Math.abs(subtotal_price - subtotal_value) < EPSILON) {
  logger.info("Subtotals updated");
}
// ...

Example 2:

BigDecimal subtotal_price = new BigDecimal("0");
// ...
BigDecimal subtotal_value = new BigDecimal(subtotal.getText().substring(1));
// ...
if(subtotal_price.compareTo(subtotal_value) == 0) {
  logger.info("Subtotals updated");
}
// ...
    
Philip Wrage
  • 1,505
  • 1
  • 12
  • 23