C中比较数大小的坑--20.10.11

最近在做个项目,涉及到两个平台之间的通信,通信协议也十分简单,协议格式如下

         AA XX XX YY YY YY YY 0A

其中"AA"是数据帧头,"XX XX"是指令内容,"YY YY YY YY"是4字节数据,"0A"是帧尾。

问题出在哪里呢,就是这4个字节的数据。规定4个字节数据是有符号的,现在要求将接收到的数据全部转化为正数,并且最大不能超过正5000。

数据解析部分十分简单,不再展示,现在直接对数据进行处理,即将数据全部转换为正数。代码如下 (buff是接收到的数据存放数组)

int dat = 0;
/* 接收数据 */
dat = (buff[3]<<24) | (buff[4]<<16) | (buff[5]<<8) | buff[6];
if(dat < 0)
{
    
    	
    dat = -dat;
}
else if(dat > 5000)
{
    
    	
    dat = 5000;
}

到这里,不知道朋友们是否发现了BUG,没错,如果一个数小于(-5000)的话,那么变成正数以后,他就大于5000。比如:取dat = -6000,那么运算完成后,dat的值是6000,因此需要对上面进行改进,有的朋友可能会这么改

dat = (buff[3]<<24) | (buff[4]<<16) | (buff[5]<<8) | buff[6];
if(dat < 0)
{
    
     
    dat = -dat;
}
if(dat > 5000)
{
    
     
    dat = 5000;
}

好了,两个if相互独立,就算dat = -6000,那么再经过下面的if语句,成功的把值限制到5000。这样写是不是已经结束了呢?还会不会有问题呢

答案是肯定的,还是存在问题。为什么呢,小伙伴们有没有认真看题目,数据是32位有符号型,数据范围是多少呢? -2^31 ~ ( 2^31 - 1)。问题出在哪里呢,没错,就是-2^31这个数。

如果取dat = -2^31,那么dat首先是小于0的,所以会首先执行第一个if语句,dat = -dat.那么此时dat是多少呢,可不是 2^31,dat还是 - 2^31,为啥,因为32位有符号数的最大正数范围就是 2^31 - 1,超出后就变为负的最大,因此第二个if语句不会执行,这个数依然还是负数。想要解决,只需要在第一个if语句中加以限制,当dat小于 - 5000时,让dat为-5000就行了。

当然,也可以写个函数,调用起来更方便。

void limit_dat(int *dat)
{
    
    
    if (*dat < 0)
    {
    
    
        if (*dat < -5000)
        {
    
    
            *dat = -5000;
;       }
        *dat = (-1)*(*dat);
    }
    if (*dat > 5000)
        *dat = 5000;
}

猜你喜欢

转载自blog.csdn.net/weixin_42952614/article/details/109013585