Thread: Very strange behavior from very simple program

  1. #1
    Registered User
    Join Date
    Dec 2009
    Posts
    41

    Very strange behavior from very simple program

    So Below is my program in its entirety. The clock() functions are giving me some very strange results. I compile it in gcc on a unix box. the clock() function at first(line 167) I print start time immediately after declaring it and the result is an incredibly long number that just cant be right.

    second, after I print the result(line 191) both the endTime Variable and just printing clock() results in it equaling the value of the variable A.

    now more fun, if I move that print statement at line 191 where i print the result below where I print clock(), both clock() and endtime prints as 0.

    I'm very confusd and have been tinkering and asking folks for help for several hours. anyone here have any ideas?

    Code:
    /*/////////////////////////////////////////////////////////////////////////////
    // Linear Curve Fitting - This program fits a line to the data points in the
    // file provided on the command line (one data point per line of text in the
    // file).
    //////////////////////////////////////////////////////////////////////////////*/
    #include <stdio.h>
    #include <stdlib.h>
    #include "data.h"
    //#include <string.h>
    #include <time.h>
    
    //////////////////////////////////////////////////////////////////////////////
    //  Class declaration for determining the "best" line for a given set of X-Y
    // data points.
    //////////////////////////////////////////////////////////////////////////////
         // X data list
         double* Data_X;
    
         // Y data list
         double* Data_Y;
         /*The length of the list*/
         int Data_len = 0;
         /*The number of elements in the lists*/
         int Data_elems = 0;
         clock_t startTime,endTime;
         // The constant 'B'
         double B;
         // The coefficient to the linear term 'A'
         double A;
         // Flag indicating that the coefficients have been computed
         int CoefficientsComputed;
    
    /*/////////////////////////////////////////////////////////////////////////////
    //  AddPoint() - Accepts a single point and adds it to the Array, Resizing if necessary
    /////////////////////////////////////////////////////////////////////////////*/
    void AddPoint(double X, double Y)
      {
        /*If the array memmory has not been allocated, Data_len will be 0, so allocate and insert first elements*/
        if (Data_len == 0){
            
            Data_X = (double*)malloc(sizeof(double)* 3);
            Data_Y = (double*)malloc(sizeof(double)* 3);
            Data_X[0] = X;
            Data_Y[0] = Y;
            Data_len = 3;
            Data_elems = 1;
            } /*if*/
        /*if the number of elements = the size of the array, double the size of the array*/    
        else if(Data_len == Data_elems){
            Data_len *= 2;
            Data_X = realloc(Data_X, (sizeof(double) * Data_len));
            Data_Y = realloc(Data_Y, (sizeof(double) * Data_len));
            /*add the X and Y to their respective arrays and increment the counter*/
            Data_X[Data_elems] = X;
            Data_Y[Data_elems] = Y;
            Data_elems++;
            }
            /*Add the elements to the array and increment the elemnt variable.*/
        else{
            Data_X[Data_elems] = X;
            Data_Y[Data_elems] = Y;
            Data_elems++;
            }
        
            
      } // AddPoint()
       
    /*/////////////////////////////////////////////////////////////////////////////
    //  GetNumberOfPoints() - Returns the number of points collected
    /////////////////////////////////////////////////////////////////////////////*/
    int GetNumberOfPoints()
      {
       return Data_elems;
      } // GetNumberOfPoints()
       
    /*/////////////////////////////////////////////////////////////////////////////
    //  ComputeCoefficients() - Calculate the value of the linear coefficient
    // 'A' and the constant term 'B' in Y = A * X + B
    /////////////////////////////////////////////////////////////////////////////*/
    void ComputeCoefficients()
      {
       // Declare and initialize sum variables
       double S_XX = 0.0;
       double S_XY = 0.0;
       double S_X  = 0.0;
       double S_Y  = 0.0;
    
       // Iterators
    
       // Compute the sums
       int lcv_X = 0;
       while (lcv_X <= Data_elems)
         {
          S_XX += (Data_X[lcv_X]) * (Data_X[lcv_X]);
          S_XY += (Data_X[lcv_X]) * (Data_Y[lcv_X]);
          S_X  += (Data_X[lcv_X]);
          S_Y  += (Data_Y[lcv_X]);
      
          // Iterate
          lcv_X++; 
         } // while()
     
       // Compute the constant
       B = (((S_XX * S_Y) - (S_XY * S_X)) / ((Data_elems * S_XX) - (S_X * S_X)));
       // Compute the linear coefficient
       A = (((Data_elems * S_XY) - (S_X * S_Y)) / ((Data_elems * S_XX) - (S_X * S_X)));
    
       // Indicate that the Coefficients have been computed
       CoefficientsComputed = 1;
      } // ComputeCoefficients()
    
    //////////////////////////////////////////////////////////////////////////////
    //  GetConstant() - Calculate the value of the constant 'B' in Y = A * X + B
    //////////////////////////////////////////////////////////////////////////////
    double GetConstant(void)
      {
       if (CoefficientsComputed == 0)
         {
          ComputeCoefficients();
         } // if()
    
       return B;
      } // GetConstant()
       
    //////////////////////////////////////////////////////////////////////////////
    //  GetLinearCoefficient() - Calculate the value of the linear coefficient
    // 'A' in Y = A * X + B
    //////////////////////////////////////////////////////////////////////////////
    double GetLinearCoefficient(void)
      {
       if (CoefficientsComputed == 0)
         {
          ComputeCoefficients();
         } // if()
    
       return A;
      } // GetLinearCoefficient()
    
    //////////////////////////////////////////////////////////////////////////////
    // Main program to fit a line to the data.
    //////////////////////////////////////////////////////////////////////////////
    int main(int argc, char *argv[])
      {
        
       // Check that a command line argument was provided
       //printf("%i", argc);
       if (argc == 2)
          {
          CoefficientsComputed = 0;
          // Variables to hold the constant and linear coefficients of the line
          
          //double A, B;
          //temp variable to find location of tab and split the string
          //char * pch;
          //element that the tab char is
          int tabLoc;
          double X, Y;
          // Temporary variables to hold data read from file
          char temp1[sizeof(double) *3];
          //start and end times
    
          //int a;
          FILE *inputFile;
          startTime = clock();
    
          //(void) time(&startTime);
          printf("%f\n",startTime);
          inputFile = fopen(argv[1],"r"); 
          ///printf("%iWOO\n", 1);
          
          //a = fscanf(inputFile, "%f\t%f", X,Y); 
          // While a data point is returned, add it to the list
          while (fgets(temp1,1000,inputFile) != NULL)
            {
             sscanf(temp1,"%lf %lf",&X,&Y);
             //pch = strchr(temp1," ");
             //tabLoc = pch; //- temp1 + 1;
            // printf(temp1);
             //printf("\n");
             // Add the data point
             AddPoint(X, Y);
             //a = 
            } /* while() */
    
          // Save the constant value and the linear coefficent
         A = GetLinearCoefficient();
         B = GetConstant();
    
          // Print out the line that fits the data set.
          endTime = clock();
          printf( "The line is: Y = %.4f * X + %.4f\n" ,A, B );
    
          printf("%fEND\n",endTime);
          printf("%fstart\n",clock());
          printf("%f\n",(double)CLOCKS_PER_SEC);
          printf("%f\n",(double)GetNumberOfPoints());
          printf( "Time per calculation = %.30f mSec", ((double)(endTime) / (double)CLOCKS_PER_SEC / (double)GetNumberOfPoints()) * 1000.0);
    
          } // if()
       else
         {
          // Display program usage information
          printf( "Usage: %s <filename>",argv[0]);
         } // if...else()
    
       return(0);
      } // main()

  2. #2
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    First, clock_t isn't guaranteed to be a float/double (it's a long on my system, but is only defined as being an arithmetic type); as such, you should not use %f to print it out. Since you're using gcc, always build with at least the -Wall option; that would have caught this problem, assuming of course that your clock_t isn't a float/double. If you really need to print out a clock_t, cast it to a large type and print that out, but you probably don't need to print it out, because...

    The absolute values that clock() returns aren't useful by themselves. There's no guarantee that the first call to clock() will return 0. What you want to do is take the difference between two calls to clock() and divide by CLOCKS_PER_SEC to get the number of seconds elapsed:
    Code:
    #include <stdio.h>
    #include <time.h>
    
    int main(void)
    {
      clock_t start, end;
      volatile int i;
    
      start = clock();
      /* something that tries to eat at least a little CPU time */
      for(i = 0; i < 10000000; i++)
        ;
      end = clock();
    
      printf("%f\n", (end - start) / (double)CLOCKS_PER_SEC);
    
      return 0;
    }

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Why are you printing clock_t data types, as floats? The processor ticks will never be anything that needs a decimal point.

    The arithmetic seems odd, as well. you need:

    elapsed time = (stopTime - startTime)/clock ticks per sec, to get the elapsed time.

    then divide the elapsed time by the number of points, to get the average time per point.
    Doing both calculations at once, including all the casts you make, is very messy.

    Number of points will never need a decimal point either. Will there ever be a fraction of a dot?

  4. #4
    Registered User
    Join Date
    Dec 2009
    Posts
    41
    Thanks, you were all right. i read the man for clock_t and it acts exactly the same as an unsigned int and can be printed as such.

    Unfortunatly i also read that it only has a precision of seconds and thats way to long for me. so I ended up using gettimeofday()... but thanks for all your help.

    I think the proper responce to my question would have been "shut up and read the dam man pages", but thanks!.

  5. #5
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    Quote Originally Posted by somekid413
    Thanks, you were all right. i read the man for clock_t and it acts exactly the same as an unsigned int and can be printed as such.
    Careful. This is not universally applicable. It may well be true for your system but need not be the case elsewhere, and so a program that assumes clock_t is unsigned int is not portable.

  6. #6
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Quote Originally Posted by somekid413 View Post
    Thanks, you were all right. i read the man for clock_t and it acts exactly the same as an unsigned int and can be printed as such.

    Unfortunatly i also read that it only has a precision of seconds and thats way to long for me. so I ended up using gettimeofday()... but thanks for all your help.

    I think the proper responce to my question would have been "shut up and read the dam man pages", but thanks!.
    I'm not familiar with Unix, but in Linux, Windows, DOS, etc., they ALL have timers with much greater accuracy than a second.

    On my system, clock() has an accuracy of a millisecond *if* the OS will support it. I have Windows XP, so it does not support that level of accuracy. It does support 1/10th of a second accuracy, however, (and frequently better), if the system is not busy running with other jobs.

    Windows XP also has a high precision timer that does a much better job, but it has an error in it for very short timings, that produces negative time jobs. On jobs that are a bit longer, it is OK.

    clock() gives you the number of processor ticks since your program began. That is a VERY fine timer, since that happens with every signal sweep through the cpu. That's why it needs to be divided by the number of clock ticks per second. Think about the amount of time that are being represented here - far less than a second, I assure you.

    time() is the function that supports only 1 second accuracy - but you're not using time(), anyway. Quit reading so damn much in those man pages!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. [Help] Simple Array/Pointer Program
    By sandwater in forum C Programming
    Replies: 3
    Last Post: 03-30-2007, 02:42 PM
  2. simple silly program
    By verbity in forum C Programming
    Replies: 5
    Last Post: 12-19-2006, 06:06 PM
  3. Simple window program
    By baniakjr in forum C++ Programming
    Replies: 5
    Last Post: 03-11-2006, 03:46 PM
  4. fopen();
    By GanglyLamb in forum C Programming
    Replies: 8
    Last Post: 11-03-2002, 12:39 PM
  5. Simple Program not working right (in C)
    By DruzeTito in forum C Programming
    Replies: 5
    Last Post: 06-01-2002, 10:14 PM

Tags for this Thread