0

I have a function discount that takes in a 'rate' parameter (a double) and updates a private variable netPrice within my class (also a double) to a reduced price. The calculation seems to work but there is a problem; it produces inaccuracies.

public class Good{
  private String name;
  private double netPrice;

  final static double VAT_RATE = 0.2;

  /**
   * The constructor instantiates an object representing a priced good.
   * @param name
   * @param netPrice
   */
  public Good(String name, double netPrice){
      this.name = name;
      this.netPrice = netPrice;
  }

  /**
   * Retrieves and reads the value of name.
   * @return the name of the good.
   */
  public String getName(){
      return name;
  }

  /**
   * Updates the value name.
   * @param name
   */
  public void setName(String name){
      this.name = name;
  } 

  /**
   * Retrieves and reads the value of netPrice
   * @return the net price of the good.
   */
  public double getNetPrice(){
      return netPrice;
  }

  /**
   * Updates the value netPrice
   * @param netPrice
   */
  public void setNetPrice(double netPrice){
      this.netPrice = netPrice;
  }

  /**
   * @return netprice adjusted for VAT
   */
  public double grossPrice(){
      return netPrice + (netPrice * VAT_RATE);
  }

  public void discount(double rate){
      double discount = (netPrice/100) * rate;
      netPrice = netPrice - discount;
  }
  /**
   * @return formatted string stating the name and the gross price of the good.
   */
  public String toString(){
      return "This " + name + " has a gross price of \u00A3 " + grossPrice();
  }

  public static void main(String[] args){
      Good milk = new Good("milk", 0.50);

      System.out.println(milk);
      milk.discount(20);
      System.out.println(milk); 
  }
} 

In the example above I'm expecting the discounted price to be £ 0.48 but I get £ 0.48000000000000004. I have no idea why this is off, so if anybody could shed some light on why this is happening that would be great.

As for the fix, I initially thought I could circumvent this problem by using the following method for rounding to 2 d.p.:

public void discount(double rate){
        double discount = (netPrice/100) * rate;
        netPrice = netPrice - discount;
        netPrice = Math.round(netPrice * 100.0) / 100.0

However this doesn't seem to work, in fact it gives me the same answer as above. Another fix could involve using BigDecimal but I don't know exactly how I could get this to work cleanly without changing my netPrice variable to a different type (something that I don't want to do). Any ideas?

J Adamson
  • 417
  • 1
  • 5
  • 13
  • Not all real numbers can be represented with a double. So if you absolutely want to keep using doubles, then fix how you **display** them. Use DecimalFormat, for example. See https://stackoverflow.com/questions/588004/is-floating-point-math-broken – JB Nizet Oct 12 '19 at 15:17
  • code is not completed, inside `discount function` where you declare`netPrice` variable – Ahmed Nabil Oct 12 '19 at 15:18
  • @ahmednabil88 netPrice is a field variable, part of a the wider class – J Adamson Oct 12 '19 at 15:19
  • @JAdamson so please update the question and put the complete code, to check also how you manage all app status – Ahmed Nabil Oct 12 '19 at 16:00
  • There, that should give you the full picture. – J Adamson Oct 12 '19 at 16:13

1 Answers1

0

For financial use Bigdecimal

Read this article

java-performance.info/bigdecimal-vs-double-in-financial-calculations/

Ennio71
  • 66
  • 6