Konrad
Konrad

Reputation: 2287

chrono duration_cast not working when doing arithmetic in cout

I do not understand the following behaviour

unsigned long begin_time = \
    std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();

//some code here

std::cout << "time diff with arithmetic in cout: " << \
    std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() - begin_time << std::endl;

unsigned long time_diff = \
    std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() - begin_time;

std::cout << "time_diff: " << time_diff << std::endl;

Output:

time diff with arithmetic in cout: <very large number (definitely not milliseconds)>
time_diff: <smaller number (definitely milliseconds)>

Why does the duration_cast not work when I do arithmetic within the cout? I have used unsigned int and int for the time_diff variable, but I always get good output when I first do the arithmetic within the variable initialization or assignment.

NOTE

I am using Visual Studio 2013 (Community edition)

Upvotes: 3

Views: 2382

Answers (2)

Holt
Holt

Reputation: 37606

There is nothing wrong with duration_cast, the problem is that an unsigned long is not large enough to handle a time in milliseconds since epoch. From ideone I get this output:

Max value for `unsigned long`: 4294967295
Milliseconds since epoch:     15426527488

I get the number of milliseconds by directly outpouting:

std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() << std::endl;

In your first output, you get a gigantic number because begin_time is cast to std::chrono::milliseconds::rep (the return type of .count()) which is large enough to handle the time_since_epoch (guaranted by the standard), while in your second output, both value are truncated by the unsigned long and thus you get a (probably) correct result.

Note: There may be architecture where an unsigned long is enough to handle this but you should not rely on it and directly use the arithmetic operators provided for std::chrono::duration.

Upvotes: 1

Howard Hinnant
Howard Hinnant

Reputation: 218700

You are probably overflowing unsigned long (sizeof is 4):

unsigned long begin_time = \
    std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();

Recommended:

using namespace std::chrono;
auto begin_time = steady_clock::now();

//some code here

std::cout << "time diff with arithmetic in cout: " << 
    duration_cast<milliseconds>(steady_clock::now() - begin_time).count() << std::endl;

Upvotes: 1

Related Questions