3

timeAとtimeBの2つのtime_t変数があります。

私がやりたいのは、timeAがtimeBと同じかどうかを確認することです。ただし、場合によっては完全に同じではなく、2つの間に1秒または2秒の差がある可能性があることを知っているので、実際に確認したいのは次のとおりです。

    if (timeB - 2sec) <= timeA <= (timeB + 2sec)

そうすることは可能ですか?

1つのオプションは、time_tを使用せず、代わりにtimeBをtm構造体として保持し、比較の直前に2秒を減算してtime_t timeBminusを作成し、次に4秒を加算してtime_ttimeBplusを作成することだと思います。問題は、数百万のtimeAとtimeBのペアを比較し、可能な限りシンプルかつ高速に保ちたいということです。

どうすればいいですか?

4

4 に答える 4

8

何かのようなもの -

if (std::fabs(std::difftime(timeA, timeB)) < 2.0) 

(ここから正確なタイプなどを確認することはできませんが、アイデアは正しいと思います)

于 2012-06-01T14:46:51.027 に答える
2

通常は秒を表しますtime_tが、実際には標準の動作ではありません。の詳細はtime_t実装に任されています(これによる

time_tを直接使用するのではstruct timespecなく、tv_secメンバーを使用して使用することをお勧めします。それらが互いに2秒の距離にあるかどうかを確認するには:

static inline bool close_enough(struct timespec &ts1, struct timespec &ts2)
{
    const int64_t sec_in_nsec = 1000000000ll;
    int64_t ts1_nsec = ts1.tv_sec * sec_in_nsec + ts1.tv_nsec;
    int64_t ts2_nsec = ts2.tv_sec * sec_in_nsec + ts2.tv_nsec;

    return ts1_nsec >= ts2_nsec - 2 * sec_in_nsec && ts1_nsec <= ts2_nsec + 2 * sec_in_nsec;
}

または、で同じ式を使用しifます。関数呼び出しは最適化されるので、心配する必要はありません。他の回答で提案されているように使用absすると、整数が浮動小数点に変換されて浮動小数点演算が実行されますが、問題ありません。

アップデート

を使用して、 2つの時間の差を取得するためにtime_t使用できます。difftimeまた:

static inline bool close_enough(time_t &t1, time_t &t2)
{
    double d = difftime(t1, t2);
    return d >= -2 && d <= 2;
}
于 2012-06-01T14:58:21.180 に答える
1
if(abs(timeA - timeB) <= 2) {
  // yay!
}
于 2012-06-01T14:46:55.850 に答える
1

コンパイラがc++11をサポートしている場合は、ctimeの代わりにchronoを使用する必要があります。

#include <iostream>
#include <chrono>
#include <tuple>

int main() {
    std::chrono::system_clock::time_point a,b;

    std::tie(a,b) = std::minmax(a,b);
    if ((b-a) < std::chrono::seconds(2)) {

    }
}

このようにして、時間の差が実際には時計の2ティックではなく、2秒未満であることがわかります。ここで、ティックは必ずしも秒ではありません。

残念ながら、クロック期間のstd :: absはありません。または、if (std::abs(b-a) < std::chrono::seconds(2))自分で書くのは簡単ですが、単に書くだけです。

template<typename Rep,typename Period>
std::chrono::duration<Rep,Period> abs(std::chrono::duration<Rep,Period> d)
{
  return std::chrono::duration<Rep,Period>(std::abs(d.count()));
}
于 2012-06-01T15:02:49.467 に答える