vendredi 11 juin 2021

unexpected bug in conversion between std::chrono::duration with different Rep

I noticed unexpected behaviour and narrowed it down to conversion from one duration to another.

#include <chrono>
#include <iostream>
#include <cmath>

using sec = std::chrono::seconds;
using fsec = std::chrono::duration<float>;
using dsec = std::chrono::duration<double>;

template<typename T>
auto count_intervals(T time_jump) -> uint32_t
{
  constexpr auto interval = sec(10);
  std::cout << "[debug] " << time_jump.count() << std::endl;
  std::cout << "[debug] " << interval.count() << std::endl;
  std::cout << "[debug] " << time_jump.count() / interval.count() << std::endl;
  printf("[debug] %f\n", time_jump.count() / interval.count());
  const uint32_t k = std::ceil(time_jump.count() / interval.count());
  std::cout << "[debug] " << k << std::endl;
  return k;
}

int main()
{
  using clock_t = std::chrono::system_clock;
  using time_point_t = typename clock_t::time_point;
  using std::chrono::duration_cast;

  const auto start_point = time_point_t();
  const auto a = start_point + sec(25);
  const auto b = start_point + sec(55);

  std::cout << count_intervals<fsec>(b - a) << std::endl;
  std::cout << count_intervals<fsec>(duration_cast<fsec>(b - a)) << std::endl;
  std::cout << count_intervals<dsec>(b - a) << std::endl;
}

I cannot figure out why std::ceil rounds up. It seems when I use dsec instead of fsec all is fine. The question is what is my mistake in case of float duration representation.

output

[debug] 30
[debug] 10
[debug] 3
[debug] 3.000000
[debug] 4
4
[debug] 30
[debug] 10
[debug] 3
[debug] 3.000000
[debug] 4
4
[debug] 30
[debug] 10
[debug] 3
[debug] 3.000000
[debug] 4
4
[debug] 30
[debug] 10
[debug] 3
[debug] 3.000000
[debug] 3
3

Aucun commentaire:

Enregistrer un commentaire