The number of pits in C-20.10.11

I am working on a project recently, involving the communication between two platforms, the communication protocol is also very simple, the protocol format is as follows

         AA XX XX YY YY YY YY 0A

Among them, "AA" is the data frame header, "XX XX" is the instruction content, "YY YY YY YY" is the 4-byte data, and "0A" is the frame end.

Where is the problem, it is these 4 bytes of data. It is stipulated that 4 bytes of data are signed, and now it is required to convert all the received data into positive numbers, and the maximum cannot exceed positive 5000.

The data analysis part is very simple and will no longer be displayed. Now the data is processed directly, that is, all the data is converted into positive numbers. The code is as follows (buff is the received data storage array)

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;
}

At this point, I don’t know if my friends have found a bug. Yes, if a number is less than (-5000), then after it becomes a positive number, it will be greater than 5000. For example: take dat = -6000, then after the calculation is completed, the value of dat is 6000, so the above needs to be improved, some friends may change it like this

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

Well, the two ifs are independent of each other, even if dat = -6000, then after the following if statement, the value is successfully limited to 5000. Is this over? Will there be any problems?

The answer is yes, there are still problems. Why, have you looked at the topic carefully? The data is a 32-bit signed type. What is the data range? -2^31 ~ (2^31-1). Where is the problem? Yes, it is the number -2^31.

If dat = -2^31, then dat is less than 0 first, so the first if statement will be executed first, dat = -dat. Then what is dat at this time, not 2^31, dat is still -2 ^31, why, because the maximum positive range of a 32-bit signed number is 2^31-1, and after exceeding it, it becomes the maximum negative value, so the second if statement will not be executed, and the number is still negative. If you want to solve it, you only need to limit it in the first if statement. When dat is less than -5000, let dat be -5000.

Of course, you can also write a function, which is more convenient to call.

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

Guess you like

Origin blog.csdn.net/weixin_42952614/article/details/109013585