gpt4 book ai didi

C++:将 __int64 转换为 unsigned long

转载 作者:可可西里 更新时间:2023-11-01 10:39:27 28 4
gpt4 key购买 nike

我想在 Windows 和 Linux 中使用以下函数,但我不确定如何将 __int64 转换为 unsigned long。像我一样投值安全吗?

getTimeInMilliseconds()
{
#ifdef _WIN32


static const __int64 magic = 116444736000000000; // 1970/1/1
SYSTEMTIME st;
GetSystemTime(&st);
FILETIME ft;
SystemTimeToFileTime(&st,&ft); // in 100-nanosecs...
__int64 t;
memcpy(&t,&ft,sizeof t);
return (unsigned long)((t - magic)/10000);
#else
struct timeval tv;
gettimeofday(&tv, NULL);
unsigned long s = tv.tv_sec * 1000;
unsigned long us = tv.tv_usec / 1000;
return s + us;
#endif
}

最佳答案

是的,它是“安全的”,因为您可以在句法上执行代码中编写的操作。将 64 位 int 降级为 32 位 long int 时,您自然会丢失前 32 位,如果您的值足够小,这不是问题,问题是您的值不在其实够小的。

两个 定义(WIN32 和非 WIN32)都存在溢出问题,不是因为您不能将 64 位 int 转换为 long,而是因为您试图填充太大的值放入太小的容器中。

问题 #1,函数名称将结果描述为“以毫秒为单位的时间”,这是错误的,两种实现都试图以微秒(千秒)而不是“毫秒”返回结果这是百万分之一秒。确定你实际拍摄的结果并适本地标记它,从长远来看减少混淆。请注意,100 纳秒(十亿分之一秒)间隔与 1/10 毫秒相同,即 1/10,000 微秒,仅供引用。

问题#2:将 FILETIME 结构转换为 long int 的“memcpy”也是错误的。 FILETIME 和 __int64 有不同的字节对齐方式,这样你就会把位放在错误的地方。要将 FILETIME 转换为 _int64,您需要这样做:

LARGE_INTEGER foo;
FILETIME baz;
__int64 bar;

foo.HighPart = baz.dwHighDateTime;
foo.LowPart = baz.dwLowDateTime;
bar = foo.Quadpart;

问题#3:一个 32 位长的 int 只能存储足够大的时间值以以秒为单位有用,即使这样也只能存储到 2038 年初,这就是为什么“timeval”有一个单独的成员表示“微秒” '只是为了让你的生活变得艰难。

如果你想在单个值中有数千秒,你需要至少 36 位,可能更像是 38-40 来有时间可以引用比 1970-2038 更稳健的时间范围内的值。由于很少有编译器支持 40 位整数,我建议只升级到完整的 64 位,除非出于某种原因你不能在这种情况下你应该想出一个更好的解决方案你正在尝试做所有事情。

关于C++:将 __int64 转换为 unsigned long,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7421675/

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