如何将时间点转换为自纪元以来的秒数并表示为double类型?

4

我正在使用一个库,其中有一个函数需要一个double类型的参数。它需要传递一个以纳秒为单位的偏移量,再加上系统时钟(system_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();

问题在于编译器指出可能会丢失数据。

你的问题中没有提到ntp。它如何成为相关标签? - eerorika
你尝试过 double newTime = static_cast<double>(timepointoffset); 或类似的代码吗? - Matt
Matt,我确实尝试过那个方法,但它并不起作用。 - ecain
如何将std::chrono::time_point转换为long类型并再次转换回来? - Ciro Santilli OurBigBook.com
5个回答

10
这个程序:
#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,双精度浮点数将开始只能表示512ns的精度。

双精度浮点数仅能在大约1969年09月18日18:00:01至1970年04月15日05:59:59的近似范围内存储带有纳秒精度的system_clock::time_point

当然,这个分析假设使用IEEE 64位双精度浮点数。


2
time_point 模板有一个成员函数time_point::time_since_epoch,该函数返回自Epoch以来的时间作为duration对象。 duration是一个模板类型,函数返回的确切持续时间类型与time_pointDuration模板参数相同。另一方面,system_clock::now()返回的time_point类型是由实现定义的。
你想要用特定的表示形式显示时间。为了实现这一点,必须拥有所需类型的时间长度。在本例中,您需要std::duration<double,std::ratio<1>>。要获取由time_since_epoch返回的正确类型的时间长度,可以使用std::chrono::duration_cast进行转换。当您拥有正确表示的持续时间后,可以使用durationcount成员函数以所需的表示形式获取时间值。

谢谢您的回答,我相信我按照您说的做了,但是我仍然收到一个警告,提示可能会有数据丢失。我做错了吗? - ecain
@Elijah,也许你是对的,或者你的代码还有其他问题。确切的警告信息和指向错误的行数应该能够揭示问题所在。 - eerorika

1

0
你可以将 timepointoffset 转换为 std::time_t,然后再转换为 double:
std::time_t offsetTimet = std::chrono::system_clock::to_time_t(timepointoffset);
double offsetDouble = static_cast<double>(offsetTimet);

请注意,尽管std::time_t通常是整数类型,但并不保证


0
所以我需要补充的是,问题在于我需要在不丢失数据的情况下完成它。我有这段代码:
通常情况下无法实现这一点。当您从整数类型转换为浮点类型时,通常会失去精度。使用floating point,位被分成尾数和指数。由于整数没有为指数分配位,因此通常有更少的位来表示值的精度。
例如,从int64_t转换为double。一个int64_t有1个符号位和63个值位。双精度有1个符号位,11个指数位和52个尾数位。因此,从int64_t(63)转换为double(52),您最多可以丢失11位信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接