chrono duration_cast not working when doing arithmetic in cout - c++

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)

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;

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.

Related

std::chrono::system_clock + now() to milliseconds and back different behavior

I'm a bit puzzled to find a portable way to convert milliseconds to std::chrono::system_time::time_point. I looks like the code :
https://godbolt.org/z/e7Pr3oxMT
#include <chrono>
#include <iostream>
int main ()
{
auto now = std::chrono::system_clock::now();
auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
auto value = now_ms.time_since_epoch();
long duration = value.count();
std::cout << duration << std::endl;
std::chrono::milliseconds dur(duration);
std::chrono::time_point<std::chrono::system_clock> dt(dur);
if (dt != now_ms)
std::cout << "Failure." << std::endl;
else
std::cout << "Success." << std::endl;
return 0;
}
should work the same on win32 and linux. But unfortunately on windows (msvc) I'm getting Failure as output.
Please, assist to understand what is wrong ?
The problem is probably
long duration = value.count();
The type long isn't necessarily 64 bits wide. The C++ standard does not define the exact size of integer types besides char. Visual Studio uses 32 bits for long even in an x64 build, for example.
Anyway, try
uint64_t duration = value.count();
in your code or just
auto duration = value.count();

Timestamp difference with two decimals c++

I have to timestamps (in µs), which are stored as a uint64_t.
My goal is to be able to get the difference between these timestamps in ms, as a float with 2 decimals.
Fx I'd like the result to be 6.520000 ms.
Though I can't seem to get them to cast correctly.
I've tried the following without any luck:
uint64_t diffus = ms.getT1 - ms.getT2
float diff = static_cast<float>(diffus);
float diffMS = diff / 1000;
std::cout << diffMS << " ms" << std::endl;
I know this wont make the float only two decimals, but I can't even get that to work.
I seem to get the same result all the time, even though I vary T1 and T2 with
srand(time(NULL));
usleep((rand() % 25) * 1000);
The output keeps being:
1.84467e+16 ms
1.84467e+16 ms
1.84467e+16 ms
1.84467e+16 ms
What is happening, and what can I do? :-)
Best regards.
I made the assumption that ms.getT1 and ms.getT2 indicated that T1 was earlier in time than T2.
In that case then you are casting a negative number to float, and the first bit is probably being interpreted incorrectly for your expectations.
The following tests confirm my assumption:
// Force diffus to be a negative number.
uint64_t diffus = 20 - 30;
float diff = static_cast<float>(diffus);
float diffMS = diff / 1000;
std::cout << diffMS << " ms" << std::endl;
// Result of casting negative integer to float.
1.84467e+16 ms
// Force diffus to be a positive number.
uint64_t diffus = 30 - 20;
float diff = static_cast<float>(diffus);
float diffMS = diff / 1000;
std::cout << diffMS << " ms" << std::endl;
// Result of casting positive integer to float.
0.01 ms
A float is normally a 32 bits number, so consider the consequences of doing this for further applications...
uint64_t diffus = ms.getT1 - ms.getT2
float diff = static_cast<float>(diffus);
on the other hand, float numbers can be represented in several ways....
(scientific notation for example) and that is only about how the number will look like, not about the number is holding..
3.1
3.14
3.14159
could be the same pi number printed in diff formats according to the needs of the application...
If your problem is about the representation of a float number then consider to set the precision of the cout object: std::cout.precision, here more info
std::cout.precision(2);
std::cout << diffMS << " ms" << std::endl;

Obtaining time difference in nanoseconds

Referring to Obtaining Time in milliseconds
Why does below code produce zero as output?
int main()
{
steady_clock::time_point t1 = steady_clock::now();
//std::this_thread::sleep_for(std::chrono::milliseconds(1500));
steady_clock::time_point t2 = steady_clock::now();
auto timeC = t1.time_since_epoch().count();
auto timeD = t2.time_since_epoch().count();
auto timeA = duration_cast<std::chrono::nanoseconds > ( t1.time_since_epoch()).count();
auto timeB = duration_cast<std::chrono::nanoseconds > ( t2.time_since_epoch()).count();
std::cout << timeC << std::endl;
std::cout << timeB << std::endl;
std::cout << timeD << std::endl;
std::cout << timeA << std::endl;
std::cout << timeB - timeA << std::endl;
system("Pause");
return 0;
}
The output:
14374083030139686
1437408303013968600
14374083030139686
1437408303013968600
0
Press any key to continue . . .
I suppose there should be a difference of few nanoseconds, because of instruction execution time.
Under VS2012, steady_clock (and high_resolution_clock) uses GetSystemTimeAsFileTime, which has a very low resolution (and is non-steady to boot). This is acknowledged as a bug by Microsoft.
Your workaround is to use VS2015, use Boost.Chrono, or implement your own clock using QueryPerformanceCounter (see: https://stackoverflow.com/a/16299576/567292).
Just because you ask it to represent the value in nanoseconds, doesn't mean that the precision of the measurement is in nanoseconds.
When you look at your output you can see that the count are nanoseconds / 100. That that means that the count is representing time in units of 100 nanoseconds.
But even that does not tell you the period of the underlying counter on which steady_clock is built. All you know is it can't be better than 100 nanoseconds.
You can tell the actual period used for the counter by using the periodmember of the steady_clock
double periodInSeconds = double(steady_clock::period::num)
/ double(steady_clock::period::den);
Back to your question: "Why does below code produce zero as output?"
Since you haven't done any significant work between the two calls to now() it is highly unlikely that you have used up 100 nanoseconds, so the answers are the same -- hence the zero.

Function Returning Negative Value

I still have not run it through enough tests however for some reason, using certain non-negative values, this function will sometimes pass back a negative value. I have done a lot of manual testing in calculator with different values but I have yet to have it display this same behavior.
I was wondering if someone would take a look at see if I am missing something.
float calcPop(int popRand1, int popRand2, int popRand3, float pERand, float pSRand)
{
return ((((((23000 * popRand1) * popRand2) * pERand) * pSRand) * popRand3) / 8);
}
The variables are all contain randomly generated values:
popRand1: between 1 and 30
popRand2: between 10 and 30
popRand3: between 50 and 100
pSRand: between 1 and 1000
pERand: between 1.0f and 5500.0f which is then multiplied by 0.001f before being passed to the function above
Edit:
Alright so after following the execution a bit more closely it is not the fault of this function directly. It produces an infinitely positive float which then flips negative when I use this code later on:
pPMax = (int)pPStore;
pPStore is a float that holds popCalc's return.
So the question now is, how do I stop the formula from doing this? Testing even with very high values in Calculator has never displayed this behavior. Is there something in how the compiler processes the order of operations that is causing this or are my values simply just going too high?
In this case it seems that when you are converting back to an int after the function returns it is possible that you reach the maximum value of an int, my suggestion is for you to use a type that can represent a greater range of values.
#include <iostream>
#include <limits>
#include <boost/multiprecision/cpp_int.hpp>
int main(int argc, char* argv[])
{
std::cout << "int min: " << std::numeric_limits<int>::min() << std::endl;
std::cout << "int max: " << std::numeric_limits<int>::max() << std::endl;
std::cout << "long min: " << std::numeric_limits<long>::min() << std::endl;
std::cout << "long max: " << std::numeric_limits<long>::max() << std::endl;
std::cout << "long long min: " << std::numeric_limits<long long>::min() << std::endl;
std::cout << "long long max: " << std::numeric_limits<long long>::max() << std::endl;
boost::multiprecision::cpp_int bigint = 113850000000;
int smallint = 113850000000;
std::cout << bigint << std::endl;
std::cout << smallint << std::endl;
std::cin.get();
return 0;
}
As you can see here, there are other types which have a bigger range. If these do not suffice I believe the latest boost version has just the thing for you.
Throw an exception:
if (pPStore > static_cast<float>(INT_MAX)) {
throw std::overflow_error("exceeds integer size");
} else {
pPMax = static_cast<int>(pPStore);
}
or use float instead of int.
When you multiply the maximum values of each term together you get a value around 1.42312e+12 which is somewhat larger than a 32 bit integer can hold, so let's see what the standard has to say about floating point-to-integer conversions, in 4.9/1:
A prvalue of a floating point type can be converted to a prvalue of an
integer type. The conversion trun- cates; that is, the fractional part
is discarded. The behavior is undefined if the truncated value cannot
be represented in the destination type.
So we learn that for a large segment of possible result values your function can generate, the conversion back to a 32 bit integer would be undefined, which includes making negative numbers.
You have a few options here. You could use a 64 bit integer type (long or long long possibly) to hold the value instead of truncating down to int.
Alternately you could scale down the results of your function by a factor of around 1000 or so, to keep the maximal results within the range of values that a 32 bit integer could hold.

Measuring time results in return values of 0 or 0.001

I am trying to use chrono::steady_clock to measure fractional seconds elapsed between a block of code in my program. I have this block of code working in LiveWorkSpace (http://liveworkspace.org/code/YT1I$9):
#include <chrono>
#include <iostream>
#include <vector>
int main()
{
auto start = std::chrono::steady_clock::now();
for (unsigned long long int i = 0; i < 10000; ++i) {
std::vector<int> v(i, 1);
}
auto end = std::chrono::steady_clock::now();
auto difference = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
std::cout << "seconds since start: " << ((double)difference / 1000000);
}
When I implement the same idea into my program like so:
auto start = std::chrono::steady_clock::now();
// block of code to time
auto end = std::chrono::stead_clock::now();
auto difference = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count()
std::cout << "seconds since start: " << ((double) difference / 1000000);
The program will only print out values of 0 and 0.001. I highly doubt that the execution time for my block of code always equals 0 or 1000 microseconds, so what is accounting for this rounding and how might I eliminate it so that I can get the proper fractional values?
This is a Windows program.
This question already has a good answer. But I'd like to add another suggestion:
Work within the <chrono> framework. Build your own clock. Build your own time_point. Build your own duration. The <chrono> framework is very customizable. By working within that system, you will not only learn std::chrono, but when your vendor starts shipping clocks you're happy with, it will be trivial to transition your code from your hand-rolled chrono::clock to std::high_resolution_clock (or whatever).
First though, a minor criticism about your original code:
std::cout << "seconds since start: " << ((double) difference / 1000000);
Whenever you see yourself introducing conversion constants (like 1000000) to get what you want, you're not using chrono correctly. Your code isn't incorrect, just fragile. Are you sure you got the right number of zeros in that constant?!
Even in this simple example you should say to yourself:
I want to see output in terms of seconds represented by a double.
And then you should use chrono do that for you. It is very easy once you learn how:
typedef std::chrono::duration<double> sec;
sec difference = end - start;
std::cout << "seconds since start: " << difference.count() << '\n';
The first line creates a type with a period of 1 second, represented by a double.
The second line simply subtracts your time_points and assigns it to your custom duration type. The conversion from the units of steady_clock::time_point to your custom duration (a double second) are done by the chrono library automatically. This is much simpler than:
auto difference = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count()
And then finally you just print out your result with the .count() member function. This is again much simpler than:
std::cout << "seconds since start: " << ((double) difference / 1000000);
But since you're not happy with the precision of std::chrono::steady_clock, and you have access to QueryPerformanceCounter, you can do better. You can build your own clock on top of QueryPerformanceCounter.
<disclaimer>
I don't have a Windows system to test the following code on.
</disclaimer>
struct my_clock
{
typedef double rep;
typedef std::ratio<1> period;
typedef std::chrono::duration<rep, period> duration;
typedef std::chrono::time_point<my_clock> time_point;
static const bool is_steady = false;
static time_point now()
{
static const long long frequency = init_frequency();
long long t;
QueryPerformanceCounter(&t);
return time_point(duration(static_cast<rep>(t)/frequency));
}
private:
static long long init_frequency()
{
long long f;
QueryPerformanceFrequency(&f);
return f;
}
};
Since you wanted your output in terms of a double second, I've made the rep of this clock a double and the period 1 second. You could just as easily make the rep integral and the period some other unit such as microseconds or nanoseconds. You just adjust the typedefs and the conversion from QueryPerformanceCounter to your duration in now().
And now your code can look much like your original code:
int main()
{
auto start = my_clock::now();
for (unsigned long long int i = 0; i < 10000; ++i) {
std::vector<int> v(i, 1);
}
auto end = my_clock::now();
auto difference = end - start;
std::cout << "seconds since start: " << difference.count() << '\n';
}
But without the hand-coded conversion constants, and with (what I'm hoping is) sufficient precision for your needs. And with a much easier porting path to a future std::chrono::steady_clock implementation.
<chrono> was designed to be an extensible library. Please extend it. :-)
After running some tests on MSVC2012, I could confirm that the C++11 clocks in Microsoft's implementation do not have a high enough resolution. See C++ header's high_resolution_clock does not have high resolution for a bug report concerning this issue.
So, unfortunately for a higher resolution timer, you will need to use boost::chrono or QueryPerformanceCounter directly like so until they fix the bug:
#include <iostream>
#include <Windows.h>
int main()
{
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
LARGE_INTEGER start;
QueryPerformanceCounter(&start);
// Put code here to time
LARGE_INTEGER end;
QueryPerformanceCounter(&end);
// for microseconds use 1000000.0
double interval = static_cast<double>(end.QuadPart- start.QuadPart) /
frequency.QuadPart; // in seconds
std::cout << interval;
}