0

I have this segment of code:

struct timeval start, end;
gettimeofday(&start, NULL);
//code I'm timing
gettimeofday(&end, NULL);
long elapsed = ((end.tv_sec-start.tv_sec)*1000000 + end.tv_usec-start.tv_usec);
ofstream timeFile;
timeFile.open ("timingSheet.txt");
timeFile << fixed << showpoint;
timeFile << setprecision(2);
timeFile << "Duration: " << elapsed << "\n";
timeFile.close();

Which will output the number of microseconds that has passed. However, if I change this line

long elapsed = ((end.tv_sec-start.tv_sec)*1000000 + end.tv_usec-start.tv_usec);

to this:

long elapsed = ((end.tv_sec-start.tv_sec)*1000000 + end.tv_usec-start.tv_usec)/1000000.0;

I get a negative value. Why does this happen?

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
Dave
  • 1,645
  • 2
  • 23
  • 39

2 Answers2

1

You are dividing by a double: 1000000.0, and casting back into an integer type.

Presuming all your start and end variables are ints (or longs), there is an awkward casting into a double, and then back into a long.

Try:

double elapsed = (double)(end.tv_sec-start.tv_sec) + (double)(end.tv_usec-start.tv)/1000000.0;
Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102
  • The OP is implying that the first form (without the divide) doesn't give the negative value, but the second form does... – Oliver Charlesworth May 15 '12 at 20:25
  • The second form will have a result as a `double` datatype; yet he's storing it in a `long` variable. Because he's not casting C++ treats it as though the data in the result is explicitly the data in `elapsed`, right? Thus he's likely to get a weird number. – Nathaniel Ford May 15 '12 at 20:29
  • `long x = (blah / 1000000.0)` is the same as `long x = (long)(blah / 1000000.0)`. – Oliver Charlesworth May 15 '12 at 20:30
  • I changed it to this: `long elapsed = ((double)(end.tv_sec-start.tv_sec) + (double)(end.tv_usec-start.tv_usec))/100000.0;` and I still get a negative value. – Dave May 15 '12 at 20:35
  • That code generates a warning: http://codepad.org/kGsGt7LB I could easily be wrong but I think you want `double elapsed`. – Nathaniel Ford May 15 '12 at 20:38
  • The new version is very wrong. You're adding seconds and microseconds together, without any scaling. You probably meant to parenthesize it differently. The code in your question, as shown, should work on a machine with 32-bit ints, at least for durations up to a little more than 2000 seconds (34 minutes or so). Are you sure you pasted the exact code? – cvoinescu May 15 '12 at 20:42
  • I changed it to a double and it didn't help. – Dave May 15 '12 at 20:45
  • Can you add debugging statements to get the exact values of your start, end, and elapsed variables? Oli was thinking clearly on the matter. – Nathaniel Ford May 15 '12 at 20:55
1

I use a timing class that I borrowed from somewhere here on SO.

#include <time.h>
#include <sys/time.h>
#include <iomanip>
#include <iostream>

using namespace std;

class Timer 
{
private:

timeval startTime;

public:

  void start()
  {
    gettimeofday(&startTime, NULL);
  }

  double stop()
  {
    timeval endTime;
    long seconds, useconds;
    double duration;

    gettimeofday(&endTime, NULL);

    seconds  = endTime.tv_sec  - startTime.tv_sec;
    useconds = endTime.tv_usec - startTime.tv_usec;

    duration = seconds + useconds/1000000.0;

    return duration;
  }

  static void printTime(double duration)
  {
    cout << setprecision(6) << fixed << duration << " seconds" << endl;
  }
};

For example:

Timer timer = Timer();
timer.start();
long x=0;
for (int i = 0; i < 256; i++)
  for (int j = 0; j < 256; j++)
    for (int k = 0; k < 256; k++)
      for (int l = 0; l < 256; l++)
        x++;
timer.printTime(timer.stop());

yields 11.346621 seconds.

For my hash function project, I get:

Number of collisions: 0
Set size: 16777216
VM: 841.797MB
22.5810500000 seconds
Community
  • 1
  • 1
Drise
  • 4,310
  • 5
  • 41
  • 66
  • I know this doesn't answer the question, but it provides a work around the problem. – Drise May 15 '12 at 20:41
  • Thanks! This will be helpful for the future. – Dave May 15 '12 at 21:00
  • I got -.101 I think it may have to do with my device I'm working on though. – Dave May 15 '12 at 23:02
  • This class was designed for Linux (and * UNIX), if I recall correctly, since typical Windows implementations record timings at the millisecond level. – Drise May 15 '12 at 23:10