-1

I am trying to iterate the value of I from 1 to 0 or from 0 to 1. But I have got some problem. Please check the following codes:

double i = 1.0;
loop{  // Just use a loop to iterate the i. This is just a pseudocode. 
       // We can use while-loop or for-loop or timer. 
       // (I know there is no keyword "loop" in java)

   i -=0.1;

   if( i == 0.0){
     // stop the loop
   }
}

In the above code, the loop will never stop because when the variable i will become 0.7000000001 when i = 0.8 - 0.1 during the loop. i will have lots of decimal number when i = 0.1 - 0.1. so it will never equal to 0.0.

I apologized if my description of my question is not clear enough for you. This may be a very easy question for pro programmers. But I cannot figure it out. Please let me know what I have done wrong.

Pshemo
  • 113,402
  • 22
  • 170
  • 242
Joey
  • 2,600
  • 11
  • 35
  • 60
  • 2
    `if (i <= 0)` will eventually end - but it might loop 10 or 11 times depending on precision. More about double (lack of) precision: http://stackoverflow.com/questions/4937402/moving-decimal-places-over-in-a-double – assylias Nov 08 '12 at 19:57
  • 1
    Your concern is correct. But what is your concrete question? – Thomas Jungblut Nov 08 '12 at 19:58
  • 1
    You can't represent a floating point value exactly using `double` or `float`. So `0.1` and `1.0` that you are using is not exact representation. You should rather use `BigDecimal` to get exact representation of floating point numbers. – Rohit Jain Nov 08 '12 at 19:59
  • @assylias Is correct, it loops 11 times and then gets to 0. But I don't quite understand the question either. – WilliamShatner Nov 08 '12 at 20:00
  • @WilliamShatner.. No, it will not get to `0`. It will get to value less than `0`. – Rohit Jain Nov 08 '12 at 20:01
  • @RohitJain Sorry, I meant then it gets below 0. – WilliamShatner Nov 08 '12 at 20:02
  • @RohitJain: You can absolutely represent a floating point value exactly using `double` or `float` - they're floating point types. But the "point" here is a *binary* point. `BigDecimal` is also a floating point type, but the point is a decimal point. – Jon Skeet Nov 08 '12 at 20:02
  • @JonSkeet.. Sorry, but I couldn't understand. As far as I know, floating point values are not stored as base 2. So, they could not be represented exactly. Or, am I missing something? – Rohit Jain Nov 08 '12 at 20:06
  • @JonSkeet. And the line that confused me in your comment is: - `But the "point" here is a binary point.`? What does that mean? – Rohit Jain Nov 08 '12 at 20:06
  • 1
    @RohitJain: It means that `double` and `float` are *floating binary point* types. `BigDecimal` is a *floating decimal point* type. So for example, the *decimal* number 0.5 (i.e. half) is 0.1 in binary, and can be represented exactly. "Floating point" is just any representation which uses two integer values: a *mantissa*, and an *exponent* to shift the "point" around. – Jon Skeet Nov 08 '12 at 20:10
  • @JonSkeet.. Ok. So, you mean that when we have value `0.5` in `double`. The number after decimal is converted to binary, and it is not the case with `BigDecimal`? Did I get it right? Can you post some good source where I can read about them in detail? – Rohit Jain Nov 08 '12 at 20:24
  • @JonSkeet.. Ok, I just got a link. I think that is a good one for this topic. -- [What Every Computer Scientist Should Know About Floating-Point Arithmetic](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html). – Rohit Jain Nov 08 '12 at 20:30
  • @JonSkeet.. I saw your [this answer](http://stackoverflow.com/a/4937424/1679863) where you said `double simply can't represent a number like 0.1 exactly`. And now I'm confused. `0.1` is a floating point number right? – Rohit Jain Nov 08 '12 at 20:51
  • thank you all. I think I have got what I want from the discussion above and the answer below. – Joey Nov 08 '12 at 21:17

3 Answers3

2

I would recommend BigDecimal usage.
I know BigDecimal is used in financial systems, and not Double or Float, to describe exact numbers with decimal dots (i.e - prices).

Read more here

Community
  • 1
  • 1
Yair Zaslavsky
  • 3,987
  • 2
  • 17
  • 25
0

Why don't you like to iterate from 1...10 and divide current value by 10? Something like this:

for(int i = 0; i <= 10; i++) {
   double value = (double) i / 10d;
}

Or if you don't void to have precision issues you can use BigDecimal:

BigDecimal value = BigDecimal.ZERO;

for(int i = 0; i <= 10; i++) {
   value = value.add(BigDecimal.valueOf(0.1d));
   double doubleVal = value.doubleValue();
}
Ruslan Platonov
  • 402
  • 4
  • 4
  • actually all answers here have taught me what I haven't known and solved my problem. However, yours is the clearest. I appreciated that. – Joey Nov 08 '12 at 21:19
0

Use integers for iteration and scale them appropriately.

i = 10;
while (i != 0)
{
    double d = i / 10.0;
    // do stuff with d

    i--;
}

This will work even if the scale factor is not representable in decimal.

Using BigDecimal will only work with decimal fractions. If for example you want to iterate by steps of one third it won't work.

starblue
  • 51,675
  • 14
  • 88
  • 146