LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 12-23-2008, 09:20 PM   #1
Bassy
Member
 
Registered: Oct 2004
Location: Venezuela
Distribution: Open SuSE v.-11.1.
Posts: 36

Rep: Reputation: 15
Lightbulb 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
 
Old 12-23-2008, 09:54 PM   #2
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
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!
 
Old 12-23-2008, 10:00 PM   #3
Bassy
Member
 
Registered: Oct 2004
Location: Venezuela
Distribution: Open SuSE v.-11.1.
Posts: 36

Original Poster
Rep: Reputation: 15
Wink 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

Last edited by Bassy; 12-23-2008 at 10:03 PM.
 
Old 12-23-2008, 10:41 PM   #4
jschiwal
LQ Guru
 
Registered: Aug 2001
Location: Fargo, ND
Distribution: SuSE AMD64
Posts: 15,733

Rep: Reputation: 682Reputation: 682Reputation: 682Reputation: 682Reputation: 682Reputation: 682
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.
 
Old 12-23-2008, 11:20 PM   #5
Bassy
Member
 
Registered: Oct 2004
Location: Venezuela
Distribution: Open SuSE v.-11.1.
Posts: 36

Original Poster
Rep: Reputation: 15
Smile

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?!?!?
 
Old 12-24-2008, 03:34 AM   #6
ErV
Senior Member
 
Registered: Mar 2007
Location: Russia
Distribution: Slackware 12.2
Posts: 1,202
Blog Entries: 3

Rep: Reputation: 62
Hi.
Quote:
Originally Posted by Bassy View Post
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;
}
 
Old 12-24-2008, 11:38 AM   #7
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by Bassy View Post
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
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.
 
Old 12-24-2008, 01:19 PM   #8
Bassy
Member
 
Registered: Oct 2004
Location: Venezuela
Distribution: Open SuSE v.-11.1.
Posts: 36

Original Poster
Rep: Reputation: 15
Talking 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

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?
 
Old 12-24-2008, 01:41 PM   #9
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by Bassy View Post
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

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.
 
Old 12-24-2008, 02:11 PM   #10
Bassy
Member
 
Registered: Oct 2004
Location: Venezuela
Distribution: Open SuSE v.-11.1.
Posts: 36

Original Poster
Rep: Reputation: 15
Wink Cool

Yep I agree!
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Can not create numerical directories popowich Linux - Server 18 01-27-2008 12:27 AM
meaning of numerical error happy78 Linux - General 1 02-17-2006 04:48 PM
The maximum numerical value of the user's ID ken80 Linux - Newbie 3 03-26-2005 11:36 AM
Numerical keypad Craqon Linux - General 2 12-15-2004 12:42 AM
Numerical recipes in C++ marios_auth Programming 0 07-08-2004 02:19 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 02:24 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration