2014-02-15 26 views
10

我觉得我会对这个有点疯狂,但它对我来说没有意义。在我看来,如果我从now()呼叫返回的任何时间点减去最小时间点,我总是应该得到一个积极的持续时间,但这不会发生。C++ 11 std :: chrono减去现在和最小

#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; 
} 

为什么打印一个负整数而不是正整数? (铛3.3或g ++ 4.8.1)

+0

没有必然关系的时钟,你想输出秒或毫秒的时间差? –

+0

谢谢你指出,我试图测试,看看我是否只是溢出,因为毫秒结果太大。我会将其更改回 – LorenVS

+2

您正在溢出计数器并获得负面结果 –

回答

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 
1

这是我想发生了(从我在Apple-llvm 5.0的调试器上观察到的):

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

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

相同的逻辑适用于减量。
所有这些说整数溢出使(now - min)实际上相当于(now + min),这必然是负面的。

+0

注意:实际上有符号整数溢出正式* undefined behavior *,因此你的解释是“实用的”,但是任何编译器(和优化器)都可能破坏这段代码。 –

+0

是的,我更多地报告了我在我的设置中观察到的情况,这恰好显示出与LorenVS观察到的相同的行为。 –

3

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

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

另一种选择是选择在哪里时代被称为是在过去,简单地说

Clock::now().time_since_epoch(); 
+0

这个解决方案的问题在于,“给我最少的时间”一直是程序员的简写,“给我一段时间,保证是一个过期的时间,不管有人选择他们的过期延迟。”我不知道如何用另一个相对时间值来做到这一点。 –

+0

这就是说,我仍然赞成这一点,因为这样做,减去大约1000小时,是我能看到的最好的解决方案。但我不明白这种行为不被视为一个错误。 –

+1

@ T.E.D。为此,我会说'clock :: min()'是正确的事情:'clock :: min() bames53