gpt4 book ai didi

c++ - 有没有可靠的方法在 double 中传递微秒时间?

转载 作者:行者123 更新时间:2023-12-03 07:57:46 25 4
gpt4 key购买 nike

我正在尝试解决一个相当烦人的问题,我需要具有亚毫秒精度时间戳的报告数据。问题在于时间戳消息字段是类型定义的 double 值。我仅为单个接收客户端打包此消息,但此消息是标准化数据服务的一部分,我无法很快修改该字段。

我正在考虑将表示 UTC 秒和微秒的两个 32 位值复制为 double 值的后果,如下所示。我不太喜欢它,但它似乎确实有效。然而,我不明白的是为什么当我反转秒和微秒时它不起作用。如果我以其他方式打包,第二次总是正确的,但微秒时间会因 (+/-) 1 - 500us 之间看似随机的值而变化

timeval tv;
gettimeofday(&tv, nullptr);
std::cout << " Original seconds: " << tv.tv_sec << "\n";
std::cout << " Original useconds: " << tv.tv_usec << "\n";
uint64_t ts = ((tv.tv_usec << 32) | tv.tv_sec);
double dts = (double)ts;
unsigned useconds = ((uint64_t)dts >> 32);
unsigned seconds = ((uint64_t)dts & 0x00000000FFFFFFFF);
std::cout << " Final seconds: " << seconds << "\n";
std::cout << " Final useconds: " << useconds << "\n";
std::cout << "diff: " << useconds - tv.tv_usec << "\n";

看了IEEE-754之后,我更加困惑了。看起来如果有任何位被歪曲,那就是较高位。

无论如何,我很想听到对此行为的解释以及有关如何可靠地完成此操作的任何建议。

最佳答案

要了解为什么会发生这种情况,您必须考虑在转换为 double 之前 ts 的值是什么。在这里的代码中,带有

uint64_t ts = ((tv.tv_usec << 32) | tv.tv_sec);

ts 的值最多为 1000000•232。 64 位double 使用 53 位尾数来存储所存储值的数字。这意味着对于小于 253 的值, double 将精确到最接近的整数,因此在转换为 double 时不会丢失任何数据。对于较大的值,double 只能存储 53 位精度,从而无法表示某些整数。

当切换微秒和秒时,ts 的值变为约 (16 亿)•232,即约 262 。由于转换为 double 时仅存储 53 个二进制精度数字,因此该数字将四舍五入到最接近的 29=512,从而导致您看到的错误。

如果我正确理解你想要做什么,你的时间戳需要微秒精度,那么你是否考虑过像这样计算以微秒为单位的总时间戳?

uint64_t ts = tv.tv_sec * 1000000 + tv.tv_usec;

这将保证微秒精度,而不会接近完美精度的 double 的 253 限制。

关于c++ - 有没有可靠的方法在 double 中传递微秒时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75610736/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com