-3

I have a simple code here, however it has not any division or complicated multiplying.

for ( double i=.1; i<=1; i+=.1) {
      System.out.println(i);
}

But in some cases value of i is not accurate, e.g. .79999999 or .600000001.

Why did this happen? How can I change this code that becomes accurate?

Maroun
  • 94,125
  • 30
  • 188
  • 241
Arman
  • 437
  • 3
  • 19
  • 5
    Because floating-point numbers are not exact. – chris Aug 12 '13 at 06:35
  • Possibly the most answer question in programming. In short you must round the result or use integer arithmetic. Try `printf("%.1f%n", i)` instead. Note: `i <= 1` is ideal either. – Peter Lawrey Aug 12 '13 at 06:35

6 Answers6

2

double is imprecise - it is designed to hold finite accuracy.

For precise "doubles", use BigDecimal:

BigDecimal d = new BigDecimal(".1");
for ( BigDecimal i= d; ! i.equals(BigDecimal.ONE) ; i = i.add(d) {
    System.out.println(i);
}
Bohemian
  • 412,405
  • 93
  • 575
  • 722
2

Floating point numbers aren't represented exactly, they lose precision. Try

for ( int i=1; i<=10; i+=1) {
      System.out.println("%.f", (double)i/10);
}
Thanushan
  • 532
  • 2
  • 8
1

Using int inside your loop will fix the problem:

for (int i=1;i<=10;i++) {
    System.out.println(i*0.1);
}

This is happening because decimal fractions might lose precision, they're not represented exactly.
You might want to to know What Every Computer Scientist Should Know About Floating-Point Arithmetic for more information.

Maroun
  • 94,125
  • 30
  • 188
  • 241
  • 2
    Downvoter, please let me know what I did wrong. We all want to learn from our mistakes. – Maroun Aug 12 '13 at 06:39
  • The link may theoretically answer the question, but [it would be preferable](http://meta.stackexchange.com/q/8259) to include the essential parts of the answer here, and provide the link for reference. – JJJ Aug 12 '13 at 06:40
  • @Juhana The link provides the answer. No need to copy paste parts from it IMHO. Reading it will answer OP question. I don't think this is a good reason for downvoting. – Maroun Aug 12 '13 at 06:41
  • @MarounMaroun: I do. Links are great for pointing to supplementary info or evidence...but for a number of reasons, the post should be able to stand on its own without them. If it can't, it's at best a half-answer. – cHao Aug 13 '13 at 06:32
1

This is a well known property of double.
Doubles store numbers in the format of 0.x * 2^y (or 1.x * 2^x).
This means not all integers are representable exactly, and, most importantly,
not all decimal fractions can be represented exactly.

I'm guessing you should be using something like BigDecimal here.

Alexander
  • 539
  • 5
  • 16
0

This is because of floating-point-operations. If you want exact value, there are special classes like BigDecimal

MrD
  • 1,255
  • 1
  • 10
  • 24
0
for (double i = .1; i <= 1; i += .1) {
    System.out.println(BigDecimal.valueOf(i).setScale(1, RoundingMode.HALF_UP));
}
Alex
  • 11,451
  • 6
  • 37
  • 52