考虑到时间点,如何将纪元作为双倍的秒数?

时间:2015-11-18 16:39:46

标签: c++ c++11 time chrono

我有一个我正在使用的库中的函数需要double作为参数。它需要传递一个纳秒类型的偏移量加上sytem_clock :: now()。到目前为止我有这个代码:

system_clock::time_point now = std::chrono::system_clock::now(); 
    auto timepointoffset = (now + desiredOffset);

我怎样才能把它变成双倍?

编辑:所以我需要补充一点,问题是我需要这样做而不会有丢失数据的风险。我有这段代码:

    system_clock::time_point now = std::chrono::system_clock::now(); 
    auto timepointoffset =  std::chrono::time_point_cast<std::chrono::nanoseconds>(now + desiredOffset);
    double value = timepointoffset.time_since_epoch().count();

问题是编译器说可能会丢失数据。

5 个答案:

答案 0 :(得分:4)

这个程序:

#include <chrono>
#include <cmath>
#include <iostream>

int
main()
{
    using namespace std::chrono;
    auto tp = system_clock::now() + 0ns;
    double t1 = tp.time_since_epoch().count();
    double t2 = std::nextafter(t1, INFINITY);
    std::cout << t2-t1 << '\n';
}

目前输出:

256

这意味着当前双倍不能准确表示自1970-01-01 00:00:00 UTC以来的纳秒数。双精度可以表示等于256ns(约四分之一微秒)的单位。

自2006-07-14 23:58:24.606847232以来一直如此。在此之前(暂时),双精度可以表示128ns的精度。

在2043-01-25 23:56:49.213694464 UTC,一个double将开始能够表示仅512ns的精度。

double只能在1969-09-18 18:00:01到1970-04-15 05:59:59的近似范围内存储具有纳秒精度的system_clock::time_point

该分析当然假设IEEE 64位双倍。

答案 1 :(得分:2)

time_point模板有一个成员函数time_point::time_since_epoch,它将自纪元以来的时间作为duration对象返回。 duration是模板类型,函数返回的确切持续时间类型与Duration的{​​{1}}模板参数相同。另一方面,time_point返回的time_point类型是实现定义的。

您想要特定表示中的时间。要实现这一点,您必须具有所需类型的持续时间。在这种情况下,您需要system_clock::now()。要获得std::duration<double, std::ratio<1>>返回的正确类型的持续时间,您可以使用time_since_epoch投射它。如果您拥有正确表示的持续时间,则可以使用std::chrono::duration_cast的{​​{1}}成员函数来获取所需表示形式的值。

答案 2 :(得分:0)

您可以将timepointoffset转换为std::time_t,然后将其转换为加倍:

std::time_t offsetTimet = std::chrono::system_clock::to_time_t(timepointoffset);
double offsetDouble = static_cast<double>(offsetTimet);

请注意,虽然std::time_t通常是整数类型,there is no guarantee

答案 3 :(得分:0)

  

所以我需要补充一点,问题是我需要这样做而不会有丢失数据的风险。我有这段代码:

一般情况下无法做到这一点。从整数类型转换为浮点类型时,通常会失去精度。使用floating point,这些位被分为尾数和指数。由于整数没有为指数分配位,因此通常用较少的精度位来表示该值。

例如,从int64_t转换为doubleint64_t有1个符号位和63个值位。 double有1个符号位,11个指数位和52个尾数位。因此,从int64_t(63)转换为double(52),您最多可以丢失11位信息。

答案 4 :(得分:0)

std::cout << std::chrono::duration_cast<std::chrono::nanoseconds>(
  std::chrono::system_clock::now().time_since_epoch()).count() << std::endl;

似乎是获得漫长的正确方法:http://en.cppreference.com/w/cpp/chrono/time_point/time_since_epoch然后您可以将其转换为双倍。