Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implicit conversion double to unsigned long overflow c++

I'm testing a timer based on the ctime library using the clock() function. Please note that the code that follows is only for test purposes.

#include <ctime>

unsigned long Elapsed(void);

clock_t start = 0;
clock_t stop = 0;

int main()
{
  start = std::clock();
  while(1)
   {
    sleep(1);
    cout << "Elapsed seconds: " << Elapsed() << endl;
   }
return 0;
}

unsigned long Elapsed()
{
  stop = std::clock();
  clock_t ticks = stop - start;
  double seconds = (double)ticks / CLOCKS_PER_SEC;  //CLOCK_PER_SEC = 1 milion
  return seconds;
}

As you can see I'm performing an implicit conversion from double to unsigned long when Elapsed() returns the calculated value. The unsigned long limit for a 32 bit system is 2,147,483,647 and I get overflow after Elapsed() returns 2146.

Looks like the function converts "ticks" to unsigned long, CLOCK_PER_SEC to unsigned long and then it returns the value. When it converts the "ticks" it overflows.

I expected it, instead, to first calculate the value in double of "ticks"/CLOCK_PER_SEC and THEN convert it to unsigned long.

In the attempt to count more seconds I tried to return a unsigned long long data type, but the variable always overflows at the same value (2147).

Could you explain me why the compiler converts to unsigned long long "a priori" and why even with unsigned long long it overflows at the same value ? Is there any way to write the Elapsed() function in a better way to prevent the overflow to happen ?

like image 217
Podarce Avatar asked Jun 21 '26 10:06

Podarce


1 Answers

Contrary to popular belief, the behaviour on converting a floating point type such as a double to any integral type is undefined if the value cannot fit into that integral type.

So introducing a double in your function is a poor thing to do indeed.

Why not write return ticks / CLOCKS_PER_SEC; instead if you can allow for truncation and wrap-around effects? Or if not, use a unsigned long long as the return value.

like image 67
Bathsheba Avatar answered Jun 24 '26 00:06

Bathsheba