游戏最近上线,在de一系列bug。其中有个bug比较有意思,是碰撞攻击Boss时,第一下总是打了不算。因为攻击Boss加了50ms的无敌间隔,以防止Boss在短时间连续碰撞中被秒杀。
遂怀疑是取系统时间出了问题,但在Mac上调试,发现输出完全无误。直到连上了iPhone5进行真机调试时,发现获取系统时间的函数输出的是一个负数。
以下是取当前系统的毫秒数。
inline long getCurrentTime()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec * 1000 + tv.tv_usec / 1000;
}
出现此问题,显然是溢出了。由于tv.tv_sec
的类型是long
,而long
在32位的机器上的范围为−2,147,483,648 -> 2,147,483,647
。
因为Mac运行的是64位的架构,而iPhone5是32位的架构,所以在Mac上没问题,而在iPhone5就出现问题了。
tv.tv_sec
表示是Unix时间戳。写下本文时的unix时间戳为1425312506
,乘1000后显然是溢出了。
解决方案很简单,用long long就行了。(读者注:在不支持long long类型的编译器上可以使用double类型。)
inline long long getCurrentTime()
{
struct timeval tv;
gettimeofday(&tv, NULL);
long long ms = tv.tv_sec;
return ms * 1000 + tv.tv_usec / 1000;
}
解决完这个bug,不禁想到当unix时间戳到了2,147,483,647
会是怎么办。这个问题早就有人考虑到了,叫做2038年问题。
也就是到了2038年1月19日3时14分07秒
后,如果在32位设备上用long
类型再表示unix时间戳就溢出了。。
第一行是“time_t”数字的二进制表示;第二行是其十进制表示;第三行是受影响的计算机理解的时间;第四行是实际的时间
不过到了2038年,还有32位设备么。。。
楼主,也可以把ms定义为double类型,long long 类型有些编译器可能不支持,在VC中也可以用__int64类型
嗯,感谢提示