Java: multiply 11 by 17.39

Discussion in 'Mac Programming' started by Howiieque, Jun 18, 2009.

  1. macrumors regular

    Joined:
    Feb 1, 2009
    #1
    hi. could you explain...
    Code:
    public class test {
    	public static void main (String [] args)
    	{
    		int a=11;
    		double b=17.39;
    		double c=a*b;
    		System.out.println(c);
    	}
    }
    
    here is what i get:
    191.29000000000002

    why not 191.29
    how to make c just 191.29
     
  2. macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
    #2
    Remember that your math is being done in base 2, and not all numbers that have finite base 10 representations also have finite base 2 representations.
     
  3. thread starter macrumors regular

    Joined:
    Feb 1, 2009
    #3
    double subtotal, price;
    int quantity;
    for (...) {
    ...
    subtotal+=price*quantity;
    }

    thanks. could you give a little more details?
    How can I fix it to ensure that the subtotal can get the right answer after the loop?
     
  4. macrumors member

    Joined:
    Jun 4, 2009
    #4
    Wikipedia will be a good place to start to understand how computers do maths. Articles of interest might include http://en.wikipedia.org/wiki/Floating_point and http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic. Java has classes such as java.math.BigDecimal that could help however...

    Chances are you can just display to only 2 decimal places when displaying your value and that will be good enough (e.g. System.out.printf("%0.2f", subTotal)).

    If you feel you need to round off after very calculation then you can do it by multiplying by 100, using round (from Math) and dividing by 100 (I am assuming 2 decimal places here). I would guess that just printing out to 2 decimal places will be sufficient for your needs though, and the least work. You should understand how the maths actually work though, by reading the wikipedia article, as one day you might have a requirement that means you need to care - and besides its interesting.
     
  5. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #5
  6. macrumors 6502

    Joined:
    May 17, 2002
    Location:
    Denver, CO
    #6
    If you're working with money in Java the best thing to do is to use the BigDecimal class. Here a quick rewrite of your application using it:

    Code:
    import java.math.BigDecimal;
    
    public class test {
       public static void main (String [] args) {
          int a = 11;
          BigDecimal b = new BigDecimal("17.39");
          BigDecimal c = b.multiply(new BigDecimal(a));
          System.out.println(c);
       }
    }
    
    If you do use the BigDecimal you'll want to become familiar with its scaling settings/methods and with the NumberFormat class.
     
  7. macrumors 65816

    Joined:
    May 21, 2009
    Location:
    Chicago
    #7
    you could always display it as a string and chop off decimal places
     
  8. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #8
    Unless it has to represent it as 1.9999999997, etc.

    If floating point can be avoided, do it.

    -Lee
     
  9. thread starter macrumors regular

    Joined:
    Feb 1, 2009
    #9
    thanks all of you and your suggestions and approaches.
    it taught me so much about dealing with money in java.
     
  10. macrumors G4

    Eraserhead

    Joined:
    Nov 3, 2005
    Location:
    UK
    #10
    FWIW this doesn't just apply to Java - but really any computer language ;).
     
  11. macrumors 6502a

    Joined:
    Oct 14, 2008
    Location:
    Brazil
    #11
    I've made this class to work with these problems using double/float when working with cash and stuff. If you want, here it goes:

    (I've translated the code, it was written on other language, if you get a build error or something else, check the syntax).

    I uploaded it (zipped, it's a java file) and posted under:

    http://kttns.org/yjbl

    Code:
    public class Coins {
    	
    	private long cents;
    	
    	public Coins()
    	{
    		this(0.0);
    	}
    	
    	public Coins(double value)
    	{
    		setValue(value);
    	}
    	
    	public double getValue()
    	{
    		return this.cents / 100.0;
    	}
    	
    	public void setValue(double value)
    	{
    		if (value >= 0)
    			this.cents = (long) (value * 100.0 + 0.5);
    		else
    			this.cents = (long) (value * 100.0 - 0.5);
    	}
    	
    	public boolean areSame(Object anotherObject)
    	{
    		if (!(anotherObject instanceof Coins))
    			return false;
    		return getValue() == ((Coins)anotherObject).getValue();
    	}
    	
    	protected long getCents()
    	{
    		return this.cents;
    	}
    	
    	public boolean isBiggerValue(Coins any)
    	{
    		if (getCents() > any.getCents())
    			return true;
    		return false;
    	}
    	
    	public boolean isLowerValue(Coins any)
    	{
    		if (getCents() < any.getCents())
    			return true;
    		return false;
    	}
    	
    	public boolean sameValues(Coins any)
    	{
    		if (getCents() == any.getCents())
    			return true;
    		return false;
    	}
    	
    	protected void setCents(long cents)
    	{
    		this.cents = cents;
    	}
    }
    
     
  12. macrumors G4

    Eraserhead

    Joined:
    Nov 3, 2005
    Location:
    UK
    #12
    You need to use the decimal classes as otherwise you can't guarantee accuracy of the numbers involved.
     
  13. thread starter macrumors regular

    Joined:
    Feb 1, 2009
    #13
    It is kind of you to provide a lot of approaches to solve the problem. I just pick up the *100 then /100 method due to my simple homework. I shall learn to use the other sophisticated methods in the future. Thank you very much.:)Especial for Wowzera providing his own class.
     
  14. macrumors G4

    Eraserhead

    Joined:
    Nov 3, 2005
    Location:
    UK
    #14
    Yeah, I should be clear I'm talking about code to be used professionally not homework ;).
     
  15. macrumors 6502a

    Joined:
    Mar 22, 2007
    Location:
    Scotland
    #15
    In my experience as a computer consultant and programmer it is most common for currency values to be stored as integer numbers of pence, cents or some other value and then for the display of this value as a floating point number to be handled at the output stage. For example store $123.45 as the integer 12345 and then use a formatting function to add the currency symbol and decimal point when displaying to the screen.

    However, more recently I find myself using Java along with BigDecimal etc.

    I'd suggest you learn both methods and get comfortable with each along with any other methods suggested by others. The important thing is to avoid using double data types unless you are doing certain types of scientific calculations where absolute accuracy is not important but speed of execution is. BigDecimal is not as fast to work with as double but is accurate.

    Craig.
     

Share This Page