LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Doubt about numerical precision (https://www.linuxquestions.org/questions/programming-9/doubt-about-numerical-precision-692633/)

Bassy 12-23-2008 09:20 PM

Doubt about numerical precision
 
Hi! I'm writing a graphical editor for curves (homework) and I've come with an instance of this algorithm:

Code:

int main(){

  float a;

  for(a = 0.0; a <= 1.0; a = a + 0.05)
    printf("%f\n", a);

  return 0;
}

Now the thing is that it doesn't print 1.0 XD Now I'd like some opinions about the implications of numerical precision here because its just additions and besides a is an increasing number.

I tried it with "double a;" but it just the same jejeje. I'm using gcc 4.1.0.

I'm pretty curious about this :D

paulsm4 12-23-2008 09:54 PM

Hi -

Here's a minor change to your program:
Code:

#include <stdio.h>

int
main ()
{
  float a;

  for (a=0.0; a <= 1.0; a += 0.05)
    printf ("%f\n", a);
  if (a == 1.0)
    printf ("%f == 1.0\n", a);
  else
    printf ("%f != 1.0\n", a);

  return 0;
}

And here's the sample output:
Quote:

0.000000
0.050000
0.100000
0.150000
0.200000
0.250000
0.300000
0.350000
0.400000
0.450000
0.500000
0.550000
0.600000
0.650000
0.700000
0.750000
0.800000
0.850000
0.900000
0.950000
1.000000 != 1.0
Hint: this is pure "C" (and floating point precision). It has nothing to do with you, your program, or GCC (in fact, I compiled/ran this under Visual Studio. You'll get similar results with ANY C compiler).

Why?

It's an important question - Google for "C" and "floating point" - I'm sure you'll find the answer.

Good luck!

Bassy 12-23-2008 10:00 PM

Nice but...
 
Thanks! I know it's not my code... and it's not my compiler neither because the original code is in C++ being compiled with g++.

I'm just curious becaise it defies intuition XD

Thanks for the interest ;) I'll google that :D

jschiwal 12-23-2008 10:41 PM

The value you use as an increment may not be exactly representable as a floating point number. In the 80's I read an article in a C-Language magazine about floating point numbers. There were so many caveats, I couldn't believe how complicated it was. A floating point library may even use approximation routines for sin() for very small angles. The routine to calculate the value depends on the input value, and isn't always a series. ( The same thing may be be happening in a floating point processor )

If you evaluate some series, you may need to process the series so that the smaller values are added first. This may mean a for loop that counts down for some series.

Never test for equality in floating point numbers. Test if the value is within a small delta from the value you want to test. Using a for loop, you might want to add a small delta value to the top value in your loop.

Bassy 12-23-2008 11:20 PM

Jajajaja I was actually thinking that.

When I took Numerical Analysis for CS at university I remember I had to evaluate series from the smallest value to the biggest I actually have those proof somewhere in my notes.

The funny thing is that if you re write it like this:

Code:

#include <stdio.h>

int main(){

  float a;

  for(a = 0.0; a <= 1.0;){
    printf("%f\n", a);
    a+=0.05;
  }
  return 0;
}

So you can change the position of the a+= 0.05. If it is after the print (like here) you loose the 1.0 but if it is before you loose the 0.0

Jajajaja nice ah?!?!?

ErV 12-24-2008 03:34 AM

Hi.
Quote:

Originally Posted by Bassy (Post 3385665)
Code:

int main(){

  float a;

  for(a = 0.0; a <= 1.0; a = a + 0.05)
    printf("%f\n", a);

  return 0;
}


Try:
Code:

int main(){

  float a;

  for(a = 0.0; a <= 1.000001; a = a + 0.05)
    printf("%f\n", a);

  return 0;
}

or
Code:

#include <stdio.h>
int main(){

  int i;

  for(i = 0; i<= 20; i++)
    printf("%f\n", (float)i/20.0f);

  return 0;
}


Sergei Steshenko 12-24-2008 11:38 AM

Quote:

Originally Posted by Bassy (Post 3385665)
Hi! I'm writing a graphical editor for curves (homework) and I've come with an instance of this algorithm:

Code:

int main(){

  float a;

  for(a = 0.0; a <= 1.0; a = a + 0.05)
    printf("%f\n", a);

  return 0;
}

Now the thing is that it doesn't print 1.0 XD Now I'd like some opinions about the implications of numerical precision here because its just additions and besides a is an increasing number.

I tried it with "double a;" but it just the same jejeje. I'm using gcc 4.1.0.

I'm pretty curious about this :D

Absolutely never write such loops:

Code:

for(a = 0.0; a <= 1.0; a = a + 0.05)
in any programming language.

Unless you are sure internally numbers are represented in decimal.

Bassy 12-24-2008 01:19 PM

Jejeje
 
Hey ErV... nice approach with the casts... and defining the epsilon... cool. I think I'm gonna' steal you the one with the casts jejejeje because is pretty elegant :)

What I did was, to let the for stop by its own imprecision and then by taking advantage of a math property of the curves I'm viewing, to make a final assignment and problem solved... it's almost like if my epsilon is defined so I can stop exactly one number earlier :D

And Sergei Steshenko...

Quote:

Unless you are sure internally numbers are represented in decimal.
You mean... that I have to be sure that the real number can actually be represented using the given precision?

Sergei Steshenko 12-24-2008 01:41 PM

Quote:

Originally Posted by Bassy (Post 3386275)
Hey ErV... nice approach with the casts... and defining the epsilon... cool. I think I'm gonna' steal you the one with the casts jejejeje because is pretty elegant :)

What I did was, to let the for stop by its own imprecision and then by taking advantage of a math property of the curves I'm viewing, to make a final assignment and problem solved... it's almost like if my epsilon is defined so I can stop exactly one number earlier :D

And Sergei Steshenko...



You mean... that I have to be sure that the real number can actually be represented using the given precision?


Not given precision, but infinite precision for the fraction you are using as step and for loop limits.

Such loops are a disaster in general case because you can't be sure how many times they are executed.

Bassy 12-24-2008 02:11 PM

Cool
 
Yep I agree! ;)


All times are GMT -5. The time now is 01:54 PM.