Let's say I have a timeInterval
parameter that's a std::chrono::duration
, but of a non-predetermined unit size - sometimes it'll be std::chrono::seconds
, sometimes std::chrono:milliseconds
, who knows.
Let's say I have a float DamagePerSecond
- to calculate the damage done over the time interval, I need to calculate the floating point value of the timeInterval
in seconds, and just multiply them.
From a lot of Googling, viewing tutorials on YouTube, and viewing solutions on here, it seems that .count()
gives whole number of seconds.
Ultimately, I just want to find:
float totalDamage = DamagePerSecond * timeIntervalInSeconds;
This seems really frustratingly hard, and it's baffling that I haven't yet seen this covered after a good hour of looking through YouTube/Googling.
auto testX = std::chrono::milliseconds(5);
auto duration_s = std::chrono::duration_cast<std::chrono::seconds>(testX);
Log(L"%f\n" duration_s.count()); // This just prints out 0.00000, probably because type mismatch
Log(L"%i\n" duration_s.count()); // This just prints out 0, because there's not a whole number second yet
I tried to follow the solution here:
How to convert std::chrono::duration to double (seconds)?
auto testX = std::chrono::milliseconds(5);
float converted = std::chrono:duration<double>(testX).count();
Log(L"%f\n", converted);
But this yields the following errors:
error C2882: 'chrono': illegal use of namespace identifier in expression
error C2143: syntax error: missing ';' before ':'
error C2059: syntax error: ':'
CodePudding user response:
You may divide any two std::chrono::duration
s of any type or period to efficiently get a count in the common type.
template <class Rep, class Period>
constexpr double seconds(std::chrono::duration<Rep,Period> d)
{
using namespace std::chrono_literals;
// How many seconds? Divide by one second!
// The units cancel out and you get a number.
return d / 1.0s;
}
Note that this technique can also give you a "count" of any unusual duration.
How many 2 minute intervals?
How many 33 nanosecond intervals?
Just divide by that amount.
CodePudding user response:
You were almost there, the syntax is this :
#include <chrono>
#include <iostream>
using namespace std::chrono_literals;
int main()
{
auto duration = 125ms;
// duration cast gives the number of counts in the unit you asked for.
auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
// convert milliseconds to seconds by dividing by 1000
auto seconds = static_cast<double>(milliseconds) / 1000.0;
std::cout << seconds << "s";
return 0;
}
Live demo : https://onlinegdb.com/r7G3QpZzT
CodePudding user response:
You could simply duration_cast
to std::chrono::duration<double>
:
template<class Duration>
constexpr double Damage(Duration d)
{
using FloatSecond = std::chrono::duration<double>;
constexpr double Dps = 1234.567;
return Dps * std::chrono::duration_cast<FloatSecond>(d).count();
}
int main()
{
using namespace std::chrono_literals;
std::cout
<< Damage(1ms) << '\n'
<< Damage(5s) << '\n'
<< Damage(1min) << '\n';
}