计算从Windows纪元到今天的纳秒数时能否获得微秒粒度?

计算从Windows纪元到今天的纳秒数时能否获得微秒粒度?

使用 Ubuntu Linux 16.04 和 g++,我想知道当我计算 Unix Epoch 或 Windows Epoch 与任意日期时间之间的纳秒数时是否可以获得微秒或毫秒粒度。我知道 time(NULL) 的 time_t 结果具有秒粒度,而 gettimeofday 的 struct timeval 结果具有毫秒粒度。

还有哪些其他方法可以解决这个问题?这不是一个编程问题。我写了一个程序来测试这个,如果需要的话我可以分享。

任何帮助是极大的赞赏。

答案1

您可以使用 来执行此操作gettimeofday()。这是在 StackOverflow 上回答,我将在这里引用:

您有两种选择来获取微秒时间戳。第一个(也是最好的)选择是直接使用类型timeval

struct timeval GetTimeStamp() {
    struct timeval tv;
    gettimeofday(&tv,NULL);
    return tv;
}

第二个,对我来说不太理想,选择是从 a 构建 uint64_t timeval

uint64_t GetTimeStamp() {
    struct timeval tv;
    gettimeofday(&tv,NULL);
    return tv.tv_sec*(uint64_t)1000000+tv.tv_usec;
}

答案2

我的答案是使用decimal64格式。

引用自https://en.wikipedia.org/wiki/Decimal64_floating-point_format:

在计算中,decimal64是一种十进制浮点计算机编号格式,在计算机内存中占用8个字节(64位)。它适用于需要精确模拟小数舍入的应用程序,例如财务和税务计算。

Decimal64 支持 16 位十进制有效数字,指数范围为 −383 至 +384,即 ±0.000000000000000×10−383 至 ±9.999999999999999×10384。 (相当于 ±0000000000000000×10−398 至 ±9999999999999999×10369。)相比之下,最常用的二进制格式的近似范围为 ±0.000000000000001×10−308 至 ±1.797693134862315×10 308.由于尾数未标准化,因此大多数有效数字少于 16 位的值都有多种可能的表示形式; 1×102=0.1×103=0.01×104,等等。零有 768 种可能的表示形式(如果包含两个带符号的零,则为 1536 种)。

Decimal64 浮点是一种相对较新的十进制浮点格式,在 IEEE 754 的 2008 版本[1] 以及 ISO/IEC/IEEE 60559:2011 中正式引入。

这是描述如何使用decimal64的链接。

https://stackoverflow.com/questions/12865585/stddecimaldecimal64- Correct-usage-g-4-6-3

答案3

Decimal64 浮动解决方案是最好的,但它需要一些带有匿名联合的编程魔法。为了将decimal64转换为std::string,您必须使用一个带有2个成员的联合(假设它的名称为S),一个decimal::decimal64输入和一个uint64_t(来自C++99的cstdint.h)输出。由于该联合具有一个decimal::decimal64 成员,该成员是C++ 类并且需要用户定义的构造函数和析构函数,因此必须使用新的放置运算符来设置输入成员值并导致输出成员值发生更改。

此外,程序员必须初始化 S 对象,例如命名为 data,如下所示:S data = {12345678987654321ULL},以便编译器不会在幕后删除联合对象。更复杂的是,decimal/decimal.h没有定义内联构造函数,内联decimal64::decimal64(decimal64 __r)。最后,用户必须为decimal64编写一个全局ostream运算符<<。

为了简化自己的生活,今天我使用 uint64_t 来表示今天 Windows 纪元的纳秒数。这个选择修复了我的 int64_t 数字溢出错误。

uint64_t 和decimal64 之间的权衡是decimal64 比uint64_t 具有更大的动态范围。此外, uint64_t 的 printf 需要特殊的格式说明符:

   #include <inttypes.h>
    uint64_t t;
    printf("%" PRIu64 "\n", t);

如果您有疑问或需要代码示例,请告诉我。

相关内容