ilya1725
ilya1725

Reputation: 4938

Convert float seconds to chrono::duration

What is the easiest and elegant way to convert float time in seconds to std::chrono::duration<int64_t, std::nano>?

Is it just converting seconds to nanoseconds and passing to the std::chrono::duration constructor?

I have tried this code:

constexpr auto durationToDuration(const float time_s)
{
    // need to convert the input in seconds to nanoseconds that duration takes
    const std::chrono::duration<int64_t, std::nano> output{static_cast<int64_t>(time_s * 1000000000.0F)};
    return output;
}

But it isn't converting well on many values of the input time_s.

Upvotes: 5

Views: 3231

Answers (1)

Howard Hinnant
Howard Hinnant

Reputation: 218700

The best way is also the easiest and safest. Safety is a key aspect of using chrono. Safety translates to: Least likely to contain programming errors.

There's two steps for this:

  1. Convert the float to a chrono::duration that is represented by a float and has the period of seconds.
  2. Convert the resultant duration of step 1 to nanoseconds (which is the same thing as duration<int64_t, std::nano>).

This might look like this:

constexpr
auto
durationToDuration(const float time_s)
{
    using namespace std::chrono;
    using fsec = duration<float>;
    return round<nanoseconds>(fsec{time_s});
}

fsec is the resultant type of step 1. It does absolutely no computation, and just changes the type from float to a chrono::duration. Then the chrono engine is used to do the actual computation, changing one duration into another duration.

The round utility is used because floating point types are vulnerable to round-off error. So if a floating point value is close to an integral number of nanoseconds, but not exact, one usually desires that close value.

But std::chrono::round is really a C++17 facility. For C++14, just use one of the free, open-source versions floating around the web (http://howardhinnant.github.io/duration_io/chrono_util.html or https://github.com/HowardHinnant/date/blob/master/include/date/date.h).

Upvotes: 6

Related Questions