【问题标题】:How do I average std::chrono::time_point? [duplicate]我如何平均 std::chrono::time_point? [复制]
【发布时间】:2022-02-08 18:52:42
【问题描述】:

给定一个std::chrono::time_point<Rep, Period>的向量,我如何找到平均时间点?

求平均值的常用算法(将所有值与std::accumulate相加,除以向量大小)不起作用,因为您不能将两个std::chrono::time_point值相加,也不能将std::chrono::time_point<Rep, Period>除以@ 987654326@

【问题讨论】:

  • 平均他们的time_since_epoch() 并从结果中得出time_point,也许?
  • @HowardHinnant:搜索没有找到那个,很奇怪。但这是一个非常直接的副本。

标签: c++ time


【解决方案1】:

您必须根据std::chrono::duration 进行计算,例如time_since_epoch

template<typename TimePoint>
TimePoint mean(auto&& range) {
    auto as_duration = std::views::transform(range, [](auto & tp){ return tp.time_since_epoch(); });
    return { std::accumulate(std::begin(as_duration), std::end(as_duration), {}) / std::size(range) };
}

【讨论】:

  • 不错的答案!作为旁注,我建议减去一个共同的平均值,例如time_point 0,在求和之前,以减少求和中整数溢出的风险。在伪代码中:average = sum(t1-t0, t2-t0, ...) / n + t0
  • 唯一的问题是系统时钟time_since_epoch 可以像int64 中保存的18 位数字一样,最多可以容纳19 位数字。使用此代码,您可以获得 10 个时间戳的整数。
  • @Homer512:您需要最小值,而不是 t0。所以总和最终是正的。如果总和为负数,则在除以 std::size(range) 之前将其转换为 size_t 时会得到一个环绕。这给出了非常令人困惑的结果(它为我触发了 Y10K 错误)
  • @MSalters 哈,不错。我会将 size_t 转换为 ptrdiff_t 。这避免了最小计算,并且由于 time_point 大于 1 个字节,因此在该转换期间没有溢出的风险。
【解决方案2】:

两个时间点的差是std::chrono::duration,这些类型你可以求和。因此,只需对第一个元素进行差分,平均,然后将平均值添加到第一个元素。您将获得平均时间点。

只需确保您获得的持续时间在汇总后不会溢出。考虑投射到std::chrono::duration&lt;double&gt;,但可能过于谨慎。

您也可以使用time_since_epoch(),而不是使用与第一个元素的差异,但我不推荐。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-05
    相关资源
    最近更新 更多