14

我觉得我对这个有点疯狂,但这对我来说没有意义。在我看来,如果我从now()呼叫返回的任何时间点中减去最小时间点,我应该总是得到一个正的持续时间,但这不会发生。

#include <chrono>
#include <iostream>

typedef std::chrono::steady_clock myclock;

int main(int argc, char **argv) {
        myclock::time_point min = myclock::time_point::min();
        myclock::time_point now = myclock::now();
        auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(now - min).count();
        std::cout << millis << std::endl;
}

为什么这会打印负整数而不是正整数?(clang 3.3 或 g++ 4.8.1)

4

3 回答 3

4

正如已经指出的,这是溢出的结果。请记住,有符号类型可以表示的最小值与最大值大致相同。如果now为正,则 和 之间的差值now明显min大于min,这意味着它的量级大于该类型的最大值可以表示的量级。

如果您想保证一个正的持续时间,那么您可以使用稳定的时钟,然后使用程序开始时间作为基准,而不是使用最小值。内置时钟持续时间均已指定,因此持续时间应该能够代表至少几百年的范围,因此除非您的程序运行时间超过此时间,否则您将获得正持续时间。

另一种选择是选择一个已知时代过去的时钟,然后简单地说

Clock::now().time_since_epoch();
于 2014-02-15T08:32:47.310 回答
1

溢出了计数器,在我的机器上,它是一个signed long long

#include <chrono>
#include <iostream>
#include <limits.h>
using namespace std;

typedef std::chrono::steady_clock myclock;

int main(int argc, char **argv) {
    myclock::time_point min = myclock::time_point::min();
    long long minl = reinterpret_cast<long long&>(min);
    cout << reinterpret_cast<long long&>(min) << endl;

    auto now = myclock::now();
    long long nowl = reinterpret_cast<long long&>(now);
    cout << reinterpret_cast<long long&>(now) << endl;

    cout << (nowl-minl) << endl;

    cout << "max of signed long long:" << LLONG_MAX << endl;

    auto millis = std::chrono::duration_cast<std::chrono::seconds>(now - min).count();
    //std::cout << millis << std::endl;
}

输出:

-9223372036854775808
13924525439448122
-9209447511415327686
max of signed long long:9223372036854775807
于 2014-02-15T08:23:06.103 回答
1

这是我认为会发生的事情(根据我在 Apple-llvm 5.0 的调试器上观察到的情况):

myclock::time_point::min()返回最早的时间点,通常在内部用整数类型表示,比如说long long int. 这种类型的最小值通常为numeric_limits<long long int>::min,即 -2^63。这个值很特殊,如果你否定它,你会得到相同的值,通过整数溢出(因为最大 long long int 是 2^63 -1):

-(-2^63) == 2^63 == (2^63 - 1) + 1 == -2^63(通过溢出)

同样的逻辑也适用于减法。
所有这一切都说明整数溢出(now - min)实际上等于(now + min),这必然是负数。

于 2014-02-15T08:25:46.013 回答