C ++:将__int64转换为unsigned long

时间:2011-09-14 19:10:05

标签: c++ windows int64

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

1 个答案:

答案 0 :(得分:1)

是的,它是“安全的”,从语法上讲,你可以在代码中写下什么。当将64位int降级为32位长整数时,您自然会丢失前32位,如果您的值足够小,这不是问题,问题是您的值不在事实够小。

两个定义(WIN32和不是)都会遇到溢出问题,不是因为你不能将64位int强制转换为long,而是因为你试图填充太大的值进入太小的容器。

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

问题#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位,除非由于某些原因你不能在这种情况下你应该为什么提出更好的解决方案你想要四处奔波。