当前位置: 首页 > 科技观察

说起数据溢出,你了解多少?_0

时间:2023-03-20 21:19:05 科技观察

前言直接看代码:uint32_tTime_Interval(){staticuint32_told_time_tick;uint32_t数据;数据=sys_time_tick_ms-old_time_tick;old_time_tick=sys_time_tick_ms;对,计算Time_Interval上次调用与下一次调用的时间差,单位ms。这里有一个风险,sys_time_tick_ms达到最大值后会溢出变为0。所以我之前代码的习惯是先判断sys_time_tick_ms和old_time_tick的大小关系。uint32_tTime_Interval(){staticuint32_told_time_tick;uint32_t数据;如果(sys_time_tick_ms>old_time_tick)数据=sys_time_tick_ms-old_time_tick;否则数据=sys_time_tick_ms+(0xFFFFFFFF-old_time_tick);old_time_tick=sys_time_tick_ms;returndata;}然而在一次和同事交流的时候,我意识到没有必要这样做,只需从sys_time_tick_ms中减去old_time_tick。下面的代码sys_time_tick_ms=0xFFFFFFFF-2;old_time_tick=sys_time_tick_ms;sys_time_tick_ms++;数据=sys_time_tick_ms-old_time_tick;printf("sys_time_tick_ms:%x数据:%d\r\n",sys_systime_tick_ms,data);sys_time_tick_ms++;data_tick_time=printf("sys_time_tick_ms:%xdata:%d\r\n",sys_time_tick_ms,data);sys_time_tick_ms++;数据=sys_time_tick_ms-old_time_tick;printf("sys_time_tick_ms:%x数据:%d\r\n",sys_time_tick_ms,data);sys_time_tick_ms++;数据=sys_time_tick_ms-old_time_tick;printf("sys_time_tick_ms:%x数据:%d\r\n",sys_time_tick_ms,data);sys_time_tick_ms++;数据=sys_time_tick_ms-old_time_tick;printf("sys_time_tick_ms:%x数据:%d\r\n",sys_time_tick_ms,data);具体打印如下:sys_time_tick_ms:fffffffedata:1sys_time_tick_ms:ffffffffdata:2sys_time_tick_ms:0data:3sys_time_tick_ms:1??data:4sys_time_tick_ms:2data:5可以看出,在这种情况下,即使sys_time_tick_ms溢出了,它不会影响正常功能。如果你很理解这个问题,你可以出去左转,这篇文章会浪费你的时间。无符号减法的本质注:本文只讨论无符号减法,有符号等数据类型我没有深究。在计算机中,无符号减法是通过二进制补码进行的,比如a-b,本质上就是a的补码+(-b的补码)。不明白补码定义的同学请自行百度。uint32_ta,b,c;a=5;b=10;c=a-b;printf("c:%x\r\n",c);打印如下:c:fffffffb。这是我们上面的结论的一个简单例子。手动模拟这个减法就很容易理解了。5的原码:00000000|00000000|00000000|0000010110原码:00000000|-10的补码:11111111|11111111|11111111|11110110.(5)complement+(-10)complement=00000000000000000000000000000101+11111111111111111111111111110110.结果是fffffffb。综上所述,发现这种合法运算可以提供对无符号加法运算的更深入理解。但是这种操作还是需要谨慎。我的测试环境是IAR7.2。建议您在使用前先进行测试。大家还是要谨慎,不要因为这个问题“捅地板”。除了在开发环境测试,还需要额外备注如下:uint32_tTime_Interval(){staticuint32_told_time_tick;uint32_t数据;数据=sys_time_tick_ms-old_time_tick;会有问题old_time_tick=sys_time_tick_ms;returndata;}建议加上这样的注释,方便别人维护,代码清晰易读。与switch语句一样,合并处理某些最好添加注释的情况。switch(data){case:0case:1//0和1一样,合并处理/*dosomething*/break;case:2/*做一些事情*/break;default:break;}总结两点:测试对应的开发环境是否有问题,养成良好的习惯,写清楚注释