5

Look at the output of this link(scroll down to see the output) to find out what I'm trying to accomplish

The problem is with the for loop on line number 9-11

for(i=0; i<=0.9; i+=0.1){
  printf("%6.1f ",i);
}

I expected this to print values from 0.0 until 0.9 but it stops after printing 0.8, any idea why ??

17
  • 9
    Don't use floating points for iteration. Commented Jan 24, 2014 at 20:04
  • 3
    welcome to the wonderful world of floating point representation. Commented Jan 24, 2014 at 20:05
  • 6
    because 0.8 + 0.1 is probably something more like 0.9000001. Floats can virtually NEVER exactly represent decimal numbers accurately. Commented Jan 24, 2014 at 20:05
  • 6
    Obligatory link: What Every Computer Scientist Should Know About Floating-Point Arithmetic Commented Jan 24, 2014 at 20:07
  • 3
    @valter: don't. that won't help. Commented Jan 24, 2014 at 20:09

5 Answers 5

7

Using float here is source of problem. Instead, do it with an int:

int i;
for(i = 0; i <= 10; i++)
   printf("%6.1f ", (float)(i / 10.0));

Output:

0.0    0.1    0.2    0.3    0.4    0.5    0.6    0.7    0.8    0.9    1.0 
Sign up to request clarification or add additional context in comments.

Comments

4

Ideally floating point should not be used for iteration, but if you want to know why change your code and see how.

for(float i=0; i<=0.9f; ){
    i+=0.1f;
    System.out.println(i);
}
    

Here is the result.

0.1
0.2
0.3
0.4
0.5
0.6
0.70000005
0.8000001
0.9000001

your 9th value exceeds 0.9.

3 Comments

Yes, but doesn't 0.9 in C also exceed 0.9 by the same amount?
Yes it does, here difference is, the increment is before printing the value.
Actually the key thing here is accumulation of errors due to summing - see my answer for at test case
1

Floating point arithmetic is inexact in computing. This is because of the way that a computer represents floating point values. Here's an excerpt from an MSDN article on the subject:

Every decimal integer can be exactly represented by a binary integer; however, this is not >true for fractional numbers. In fact, every number that is irrational in base 10 will also be >irrational in any system with a base smaller than 10.

For binary, in particular, only fractional numbers that can be represented in the form p/q, >where q is an integer power of 2, can be expressed exactly, with a finite number of bits.

Even common decimal fractions, such as decimal 0.0001, cannot be represented exactly in >binary. (0.0001 is a repeating binary fraction with a period of 104 bits!)

Link to the full article: https://support.microsoft.com/kb/42980

Comments

1

Floating point number cannot precisely represent decimals, so rounding errors accumulate:

#include <iostream>
#include <iomanip>
using namespace std;

int main() {
    float literal = 0.9;
    float sum = 0;
    for(int i = 0; i < 9; i++)
        sum += 0.1;

    cout << setprecision(10) << literal << ", " << sum << endl;
    return 0;
}

Output:

0.8999999762, 0.9000000954

Comments

0

You loop is right, but the float comparison in loops is not safe. The problem is that a binary floating point number cannot exactly represent 0.1

This would work.

    for(i=0.0; i<=0.9001; i+=0.1){
           printf("%6.1f ",i);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.