首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C- timeval到uint64_t

C- timeval到uint64_t
EN

Stack Overflow用户
提问于 2020-04-21 22:50:32
回答 2查看 432关注 0票数 4

早上!

我正在尝试从时间结构中获取纳秒时间戳(uint64_t)。

代码语言:javascript
运行
复制
    struct timeval t;
    // initialized so that ....
    print("t sec: %ld, micro sec: %ld", t.tv_sec, t.tv_usec);
    // .... prints "t sec: 4, micro sec: 130728"

    long int sec = (long int) t.tv_sec;
    // just did that because I thought that using time_t in calculations may cause errors
    // print("%ld", sec) -> 4, so this seems to work as expected    

    uint64_t t_int = (sec * 1000000 + t.tv_usec) * 1000; // should be nanoseconds
    print("t_int (uint64_t) %llu", t_int);
    // prints "t_int (uint64_t) 18446744073545312320"

我的时间应该完全适合uint64_t。另外,从time_t到long int的强制转换可以工作,所以我所做的只是两个长int的简单计算,将结果放到一个uint64_t中,所以我不确定为什么我得到了一个明显错误的值。有什么想法吗?这只是一种错误的格式化方式(使用%llu)吗?

EN

回答 2

Stack Overflow用户

发布于 2020-04-21 23:11:12

以下任一项:

代码语言:javascript
运行
复制
uint64_t t_int = ((uint64_t)t.tv_sec * 1000000 + t.tv_usec) * 1000;

或者:

代码语言:javascript
运行
复制
uint64_t t_int = (t.tv_sec * 1000000ULL + t.tv_usec) * 1000;

后者跳过强制转换,而是通过让*的右侧操作数已经是至少64位的类型(而不是将左侧强制转换为1)来执行升级。两者都有效;这是一个你喜欢哪种风格的问题。

不要像您那样使用long类型的临时变量。long可能是32位类型,不适合2038年1月之后的时间。如果您需要临时变量,请将其设置为time_tint64_t或类似的变量。但这是不必要的。

此外,您可能希望考虑使用int64_t (并将ULL更改为LL)而不是uint64_t,这样您就可以表示1970年之前的时间。

票数 3
EN

Stack Overflow用户

发布于 2020-04-21 22:57:31

您正在使用long int宽度进行计算。因为它溢出,所以会发生未定义的行为,并将一些负值分配给uint64_t,这会导致一个很大的正值(在您的体系结构上)。使用uint64_tunsigned long long精度进行计算。要想学究,就转换所有的值:

代码语言:javascript
运行
复制
uint64_t t_int = ((uint64_t)sec * 1000000ull + (uint64_t)t.tv_usec) * 1000ull; 

但由于促销的原因,很可能只将一个值传递给uint64_t就足够了:

代码语言:javascript
运行
复制
uint64_t t_int = ((uint64_t)sec * 1000000 + t.tv_usec) * 1000;
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61346439

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档