【问题标题】:C++: converting __int64 to unsigned longC++:将 __int64 转换为 unsigned long
【发布时间】:2011-09-14 19:10:04
【问题描述】:

我想在 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
}

【问题讨论】:

  • 在 Windows 中 __int64 是 8 个字节宽,但 unsigned long 是 4 个字节长。这个问题没有答案。
  • 是的,直到 2038 年 1 月 19 日星期二 03:14:07 UTC。
  • 正好在我生日那天 :) 我希望到 2038 年 Windows 将早已不复存在。
  • @Vlad 您希望在 2038 年之前摆脱 *nix。Y2K38 错误是 *nix 问题而不是 Windows 问题! ;-)
  • @David:对不起,我误解了你的“没有解决方案”。事实上,我指出解决方案存在,但在另一个“域”中。

标签: c++ windows int64


【解决方案1】:

是的,从语法上讲,它是“安全的”,您可以按照代码中的内容进行操作。当将 64 位 int 降级为 32 位长 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 位,除非出于某种原因您不能在这种情况下,您应该提出一个更好的解决方案你正在尝试做所有事情。

【讨论】:

  • 澄清一下,我相信 Siegurt 的答案有错误的毫秒和微秒,所以有问题的函数的命名没有问题。 1 秒 = 1e3 毫秒 = 1e6 微秒 = 1e9 纳秒。
  • 你有毫秒和微秒的错误方式。 Microsecond 是 10-6(即百万分之一)。 Millisecond 是 10-3(即千分之一)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-04
  • 2016-12-20
  • 1970-01-01
相关资源
最近更新 更多