按照这个线程纳秒运行进入溢出,我的目的是自由地从纳秒和秒转换,但不会丢失任何信息(鉴于根据
std::chrono::nanoseconds
,纳秒是64位)。基本上,下面的代码会丢失很多信息:
std::chrono::nanoseconds t1(1705218518267805576);
std::chrono::seconds t2(std::chrono::duration_cast<std::chrono::seconds>(t1));
std::chrono::nanoseconds t3(std::chrono::duration_cast<std::chrono::nanoseconds>(t2));
EXPECT_EQ(t1,t3);
最后一行将返回 false。因此,我考虑添加诸如
long_data_seconds
之类的类型,它可以保存丢失的信息,但我不知道到底丢失了多少信息以及如何存储它以供将来转换使用。我很想听听想法。
非常感谢。
您面临的问题并不是(真的)由于
std::chrono::seconds
类型不够宽(即没有足够的位)来保存 nanoseconds
值1的完整数据;相反,这是因为 seconds
类型是 integer。因此,当您将纳秒转换为秒时,由于截断,该值的小数部分(即小于 109的数据)的所有信息都会丢失。
在您的情况下,您需要为中间“秒”数据定义一个“浮点”持续时间类型。对于您给出的示例(1,705,218,518,267,805,576 ns),IEEE-754 double
类型不够精确,因此您需要一个支持
扩展精度
long double
类型的平台,并使用它。这是一个简短的示例代码:
#include <iostream>
#include <chrono>
int main()
{
using ld_seconds = std::chrono::duration<long double, std::ratio<1>>;
constexpr std::chrono::nanoseconds t1(1705218518267805576);
constexpr ld_seconds t2(std::chrono::duration_cast<ld_seconds>(t1));
constexpr std::chrono::nanoseconds t3(std::chrono::duration_cast<std::chrono::nanoseconds>(t2));
static_assert(t1 == t3, "Not equal!");
return 0;
}
这是关于Compiler Explorer
long double
相当于
double
(例如 MSVC/Windows),那么您将需要使用第三方扩展精度库。
事实上,标准规定 std::chrono::seconds
至少35 位 - 并且许多(大多数)当前平台没有大于 34 位但小于 64 位的内置整数类型,因此在这些系统上它可能是
int64_t
。