what's with gcc?

Please support our C++ advertiser: Intel Parallel Studio Home
Reply

Join Date: Dec 2005
Posts: 5,850
Reputation: Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute 
Solved Threads: 749
Team Colleague
Salem's Avatar
Salem Salem is offline Offline
Void main'ers are DOOMed

Re: what's with gcc?

 
1
  #21
May 16th, 2006
I don't know why you edited the file when the #ifdef was there just to make it so you didn't need to edit it :shrug:

Anyway, I'm now seeing the same problem on cygwin as well - which I suppose is progress in itself.

Here's my modified code - it's the same with a bit of extra debug on the end
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3.  
  4. int main(void)
  5. {
  6. double x0,x1,a;
  7. int i;
  8.  
  9. x1 = 1;
  10. x0 = 0;
  11. printf("Find square root of: ");
  12. fflush(stdout);
  13. scanf("%lf",&a);
  14. for(i = 0; i < 100 && x0 != x1; ++i)
  15. {
  16. x0 = x1;
  17. x1 = .5 * (x1 + a / x1);
  18. #ifdef INCLUDE_PRINTF
  19. printf("Iteration %d - converging to %f - prev value %f\n",i,x1,x0);
  20. #endif
  21. }
  22.  
  23. printf("Finished in %d iterations\n",i);
  24. printf("Results: %.15f, %.15f\n",x0,x1);
  25. {
  26. union { double a; unsigned long b[2]; } v;
  27. v.a = x0;
  28. printf( "X0 in binary = %lu %lu\n", v.b[0], v.b[1] );
  29. v.a = x1;
  30. printf( "X1 in binary = %lu %lu\n", v.b[0], v.b[1] );
  31. }
  32. return 0;
  33. }

Here are my results - the last two are the more interesting ones
  1. $ gcc -W -Wall -ansi -pedantic -O2 -DINCLUDE_PRINTF foo.c
  2. $ ./a.exe
  3. Find square root of: 5
  4. Iteration 0 - converging to 3.000000 - prev value 1.000000
  5. Iteration 1 - converging to 2.333333 - prev value 3.000000
  6. Iteration 2 - converging to 2.238095 - prev value 2.333333
  7. Iteration 3 - converging to 2.236069 - prev value 2.238095
  8. Iteration 4 - converging to 2.236068 - prev value 2.236069
  9. Iteration 5 - converging to 2.236068 - prev value 2.236068
  10. Iteration 6 - converging to 2.236068 - prev value 2.236068
  11. Finished in 7 iterations
  12. Results: 2.236067977499790, 2.236067977499790
  13. X0 in binary = 2610427048 1073865591
  14. X1 in binary = 2610427048 1073865591
  15.  
  16. $ gcc -W -Wall -ansi -pedantic -O2 foo.c
  17. $ ./a.exe
  18. Find square root of: 5
  19. Finished in 100 iterations
  20. Results: 2.236067977499790, 2.236067977499790
  21. X0 in binary = 2610427048 1073865591
  22. X1 in binary = 2610427048 1073865591
  23.  
  24. $ gcc -W -Wall -ansi -pedantic -O2 -ffloat-store foo.c
  25. $ ./a.exe
  26. Find square root of: 5
  27. Finished in 7 iterations
  28. Results: 2.236067977499790, 2.236067977499790
  29. X0 in binary = 2610427048 1073865591
  30. X1 in binary = 2610427048 1073865591
  31. $

Now, the real explanation becomes more apparent when you read the manual page for that flag.
  1. `-ffloat-store'
  2. Do not store floating point variables in registers, and inhibit
  3. other options that might change whether a floating point value is
  4. taken from a register or memory.
  5.  
  6. This option prevents undesirable excess precision on machines such
  7. as the 68000 where the floating registers (of the 68881) keep more
  8. precision than a `double' is supposed to have. Similarly for the
  9. x86 architecture. For most programs, the excess precision does
  10. only good, but a few programs rely on the precise definition of
  11. IEEE floating point. Use `-ffloat-store' for such programs, after
  12. modifying them to store all pertinent intermediate computations
  13. into variables.
  14.  
With less code there (without the printf), the compiler can optimise out some implied floating point store and load instructions, which wash away the last few bits of precision which are present in the FPU registers, but not present in a double. By losing this extra precision, your loop takes a different number of iterations to complete.

Now, if you combine all this with
  1. $ gcc -W -Wall -ansi -pedantic -O2 -ffloat-store -Wfloat-equal foo.c
  2. foo.c: In function `main':
  3. foo.c:14: warning: comparing floating point with == or != is unsafe
  4.  
Which brings us nicely back to the start of the argument which I said that you can't compare floating point numbers, but which you keep insisting is OK and keep ignoring what people with vastly more experience than you keep telling you.

> That's not very elegant IMHO.
Robust use of floating point is no easy ride.
Reply With Quote Quick reply to this message  
Join Date: Apr 2004
Posts: 353
Reputation: Asif_NSU is on a distinguished road 
Solved Threads: 2
Asif_NSU's Avatar
Asif_NSU Asif_NSU is offline Offline
Posting Whiz

Re: what's with gcc?

 
1
  #22
May 16th, 2006
Which brings us nicely back to the start of the argument which I said that you can't compare floating point numbers, but which you keep insisting is OK and keep ignoring what people with vastly more experience than you keep telling you.
Yeah! But you did not give any explanation that time and it worked well on all the other compilers. All my common sense told me it's something to do with gcc - the compiler itself. Besides the warning for floating point equality is there because you made the compiler to throw that warning by -Wfloat-equal. Even now I feel -ffloat-store should have been activated by default.

And should not be these details like how it's stored in the FPU be well hidden from the programmers point of view? We are only supposed to think in terms of the datatype present in the C programming language. It looks like I have to understand all the nitty gritty internal details of the compiler before actually compiling a very simple program with it.

So is there no way other than for(i = 0; i < 50; ++i)? Come on man! There has to be a better way. What am I gonna do if I am asked why I run the loop for 50 times even for numbers that require only 6 or 7 iterations? Tell them to visit this link?
"He who mixes with people and endures the harm they do is better than he who does not mix and endures." (Tirmidhi)
Reply With Quote Quick reply to this message  
Join Date: Apr 2004
Posts: 4,343
Reputation: Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future 
Solved Threads: 237
Team Colleague
Dave Sinkula's Avatar
Dave Sinkula Dave Sinkula is offline Offline
long time no c

Re: what's with gcc?

 
0
  #23
May 16th, 2006
Originally Posted by Asif_NSU
There has to be a better way.
How about the way that was mentioned via the link in post #7? (Which was not to compare floating point values for equality -- a recurring theme in this thread, by the way.)
Originally Posted by Salem
http://c-faq.com/fp/fpequal.html
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <float.h>

int main(void)
{
   double x0 = 0, x1 = 1, a;
   int i;
   printf("Find square root of: ");
   fflush(stdout);
   scanf("%lf",&a);
   for ( i = 0; i < 100 && x0 != x1; ++i )
   {
      x0 = x1;
      x1 = .5 * (x1 + a / x1);
#ifdef INCLUDE_PRINTF
      printf("Iteration %d - converging to %f - prev value %f\n",i,x1,x0);
#endif
      {
         double epsilon = DBL_EPSILON * fabs(x1);
         if ( fabs(x1 - x0) <= epsilon )
         {
            printf("reached epsilon of %g\n", epsilon);
            break;
         }
      }
   }
   printf("Finished in %d iterations\n",i);
   printf("Results: %.15f, %.15f\n",x0,x1);
   return 0;
}
My outputs are as follows.
H:\Forum\C>C:/Dev-Cpp/bin/gcc.exe -W -Wall -ansi -pedantic -O2 ../main.c

H:\Forum\C>a
Find square root of: 5
reached epsilon of 4.96507e-016
Finished in 6 iterations
Results: 2.236067977499790, 2.236067977499790

H:\Forum\C>a
Find square root of: 7
reached epsilon of 5.87475e-016
Finished in 6 iterations
Results: 2.645751311064591, 2.645751311064591

H:\Forum\C>C:/Dev-Cpp/bin/gcc.exe -W -Wall -ansi -pedantic -O2 -DINCLUDE_PRINTF ../main.c

H:\Forum\C>a
Find square root of: 5
Iteration 0 - converging to 3.000000 - prev value 1.000000
Iteration 1 - converging to 2.333333 - prev value 3.000000
Iteration 2 - converging to 2.238095 - prev value 2.333333
Iteration 3 - converging to 2.236069 - prev value 2.238095
Iteration 4 - converging to 2.236068 - prev value 2.236069
Iteration 5 - converging to 2.236068 - prev value 2.236068
Iteration 6 - converging to 2.236068 - prev value 2.236068
reached epsilon of 4.96507e-016
Finished in 6 iterations
Results: 2.236067977499790, 2.236067977499790

H:\Forum\C>a
Find square root of: 7
Iteration 0 - converging to 4.000000 - prev value 1.000000
Iteration 1 - converging to 2.875000 - prev value 4.000000
Iteration 2 - converging to 2.654891 - prev value 2.875000
Iteration 3 - converging to 2.645767 - prev value 2.654891
Iteration 4 - converging to 2.645751 - prev value 2.645767
Iteration 5 - converging to 2.645751 - prev value 2.645751
Iteration 6 - converging to 2.645751 - prev value 2.645751
reached epsilon of 5.87475e-016
Finished in 6 iterations
Results: 2.645751311064591, 2.645751311064591
"One of the methods used by statists to destroy capitalism consists in establishing controls that tie a given industry hand and foot, making it unable to solve its problems, then declaring that freedom has failed and stronger controls are necessary." --Ayn Rand
Reply With Quote Quick reply to this message  
Join Date: Dec 2005
Posts: 5,850
Reputation: Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute 
Solved Threads: 749
Team Colleague
Salem's Avatar
Salem Salem is offline Offline
Void main'ers are DOOMed

Re: what's with gcc?

 
0
  #24
May 16th, 2006
> So is there no way other than for(i = 0; i < 50; ++i)? Come on man! There has to be a better way
yes, you code something which works on either absolute or relative errors, which we're now getting pretty fed up of telling you about.

> Besides the warning for floating point equality is there because you made the compiler to throw that warning
Do you imagine that compiler writers just throw these things in for fun, or because there is a real problem which needs to be addressed?

The lack of a warning from the compiler does not constitute a proof of correctness on your part.

> Even now I feel -ffloat-store should have been activated by default.
Erm, read the help for that flag - it serves no purpose unless you specifically rely on a particular FP behaviour (like you do).
Better written code wouldn't give a toss about the extra precision, and would get a performance benefit by not being always forced into load-store operations just for your benefit.

> have to understand all the nitty gritty internal details of the compiler
WRONG!!!!!
You need a better understanding of the language, not the implementation.

Knowing how the foo compiler implements it will not help you at all with understanding the bar compiler.

Knowing the standard inside out is what allows you to write portable code, not the grubby details of a specific implementation.

> Yeah! But you did not give any explanation that time and it worked well on all the other compilers
Are you paying for a 24hr service?
Since you insist on writing code with undefined behaviour, there are many many possible ways in which it could be going wrong.

I mean, you never posted your command line options until today.

So until someone else (me) managed to guess which options you were using, or at least some options which showed up the same problem, it was all finger in the air stuff.
Reply With Quote Quick reply to this message  
Join Date: Apr 2004
Posts: 353
Reputation: Asif_NSU is on a distinguished road 
Solved Threads: 2
Asif_NSU's Avatar
Asif_NSU Asif_NSU is offline Offline
Posting Whiz

Re: what's with gcc?

 
0
  #25
May 16th, 2006
Well, atleast I think I have learned some very good lessons from this thread.

Next time I post at daniweb C and C++ forum I promise I will be at a different level than I am currently now - which despite my efforts has remained to be "a-bit-better-than-beginner", although it has already been 2 years since I was introuduced to C. Looks like I need to take some hiatus from my usual university work if I want to gain any workable skill in C.

Take care...until we meet again.
"He who mixes with people and endures the harm they do is better than he who does not mix and endures." (Tirmidhi)
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:


Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC