使用std :: chrono :: duration_cast进行1秒和2秒的奇怪结果

iam*_*ind 5 c++ duration c++11 c++-chrono output

我运行一个简单的程序在那里,我采取了time_pointsystem_clock::nowthis_thread::sleep_for(seconds(1))和再次time_pointsystem_clock::now.

现在,如果我duration在第一个添加一些额外的内容time_point,它会在1秒和2秒内给出完全相同的结果!

这是演示代码:

#include<iostream>
#include<chrono>
#include<thread>
using namespace std;

void CheckDuration (std::chrono::duration<int> seconds)
{
  auto start = std::chrono::system_clock::now() + seconds;
  std::this_thread::sleep_for(std::chrono::seconds(1));
  auto stop = std::chrono::system_clock::now();

  cout << "Difference = " << std::chrono::duration_cast<std::chrono::seconds>(stop-start).count() << endl;
}

int main ()
{
  CheckDuration(std::chrono::duration<int>(0));  // Difference = 1
  CheckDuration(std::chrono::duration<int>(1));  // Difference = 0 
  CheckDuration(std::chrono::duration<int>(2));  // Difference = 0  <=== ???
  CheckDuration(std::chrono::duration<int>(3));  // Difference = -1
}
Run Code Online (Sandbox Code Playgroud)

How*_*ant 7

它澄清了添加更精细单位的输出,例如:

cout << "Difference = " << std::chrono::duration_cast<std::chrono::milliseconds>(stop-start).count() << endl;
Run Code Online (Sandbox Code Playgroud)

对我来说,对于第三种情况(参数2秒),输出为:

Difference = -998
Run Code Online (Sandbox Code Playgroud)

(以毫秒为单位)

要分析这一点,让T0代表时间now()在第一次调用CheckDuration.所以:

start == T0 + 2s
Run Code Online (Sandbox Code Playgroud)

stop在T0调用,加1秒钟进行休眠,再加上我们称之为epsilon的一小部分处理时间.所以:

stop == T0 + 1s + epsilon
Run Code Online (Sandbox Code Playgroud)

减去这两个,我们得到:

T0 + 1s + epsilon - (T0 + 2s)
Run Code Online (Sandbox Code Playgroud)

简化:

epsilon - 1s
Run Code Online (Sandbox Code Playgroud)

就我而言,epsilon == 2ms

duration_cast当无法准确转换时,截断行为为零.所以-998ms截断为0.对于其他可能有助于计算的持续时间和时间点舍入模式,请参阅:

http://howardhinnant.github.io/duration_io/chrono_util.html