好久没写博客了,昨天遇到一个时间计数溢出问题, 做个简单记录吧
背景:底层提供一个unsigned int的变量表示自开机以来累计时间,用作码流的时间戳,单位ms.
问题:32位无符号数的毫秒计数,大概49天就会溢出,溢出后时间计数用作时间戳就会出错,导致无法正确解码。
为解决这一问题,用一个64位变量来保存累计时间,
方法如下:
点击(此处)折叠或打开
- unsigned long long ullCurFrmPts=0;//app里用到的时间戳,微秒计
- unsigned int bf_stamp=0;
- unsigned int timestamp=0;//SDK提供的时间戳
-
- bf_stamp = ullCurFrmPts&0xffffffff);
- if(timestamp*1000 < bf_stamp) {
- ullCurFrmPts = (ullCurFrmPts + 1<<32);
- }
-
- ullCurFrmPts = (ullCurFrmPts&0xffffffff00000000)+timestamp*1000;
运行,时间怎么都不对
找问题步骤1:
先确定32位ARM上实现的unsigned long long是否64位?
测试代码
点击(此处)折叠或打开
- int num=0;
- unsigned long long test=0;
- test = ~0;
- printf("test is %llx\n",test);
- num=0;
- while(1){
- if(test&0x1){
- num++;
- }
- test = test>>1;
- if (test == 0)break;
- printf("test is %llx\n",test);
- }
- printf("test is %dbit\n",num);
执行结果如下
点击(此处)折叠或打开
- [root@GM]# ./test
- test is ffffffffffffffff
- test is 7fffffffffffffff
- test is 3fffffffffffffff
- ...
- test is 1f
- test is f
- test is 7
- test is 3
- test is 1
- test is 64bit
步骤二:添加测试代码
点击(此处)折叠或打开
- test = 3;
- printf("test0 is %llx\n",test);
- test += 1<<32;
- printf("test1 is %llx\n",test);
test is 64bit
test0 is 3
test1 is 3
问题出现了,test的值没叠加上去。
改为test += 0x100000000
执行结果如下:
test0 is 3
test1 is 100000003
结论,1<<32在32位的ARM芯片上是不是默认用一个32位寄存器左移,导致左移溢出,结果就是0?
再加个测试:
点击(此处)折叠或打开
- test = 3;
- printf("test0 is %llx\n",test);
- test += 0x100000000;
- printf("test1 is %llx\n",test);
-
- test = (test&0xffffffff00000000) + 8 ;
- printf("test2 is %llx\n",test);
- test = (test&0xffffffff) + 1;
- printf("test3 is %llx\n",test);
所以问题解决,正确代码如下:
点击(此处)折叠或打开
- unsigned long long ullCurFrmPts=0;//app里用到的时间戳,微秒计
- unsigned int bf_stamp=0;
- unsigned int timestamp=0;//SDK提供的时间戳
-
- bf_stamp = ullCurFrmPts&0xffffffff);
- if(timestamp*1000 < bf_stamp) {
- ullCurFrmPts = (ullCurFrmPts + 0x100000000);
- }
- ullCurFrmPts = (ullCurFrmPts&0xffffffff00000000)+timestamp*1000;
PS:近一年没写博客了,CU的排版还是这么垃圾,失望至极。
相关热门文章
给主人留下些什么吧!~~
评论热议