2017-07-21 25 views
0

我正在一个函数,我必须转换一个3字节的数组,并返回3字节数组作为一个单一的int32。 代码如下: pbData是指向字节数组的指针。设置最重要的符号位(林特警告)

const byte bMSBitPosNeg = 0x80; 
const byte bMSBNeg = 0xFF; 
int32 i32Num = 0; 

//Big - Endian 
if (pbData != NULL) 
{ 
    if ((pbData[0] & bMSBitPosNeg) == bMSBitPosNeg) //Negative 
    { 
     i32Num |= (bMSBNeg * 0x1000000); //Force MSB to 0xFF as 3 bytes are 
             //converted to 4 bytes 
    } 

    i32Num |= (pbData[0] << 16); 
    i32Num |= (pbData[1] << 8); 
    i32Num |= (pbData[2]); 

} 
return i32Num; 

输入:{0x00,0xBB,0xA3执行} 输出:48035 //正数

输入:{0xff的,0x44,0x5d} 输出:-48035 //负数

代码按预期工作,但我得到一个皮棉警告。 警告648:溢出运算的常量:'乘法'

我需要功能,但不想警告。我该如何抑制它?

+0

在'0x1000000'常数上使用'UL'后缀 –

+0

如果你将乘法作为相应的移位,那么它是否有意义呢?请记住,您正在使用'int',它是一种**签名的** 32位类型(在大多数平台上)。 –

+0

一般提示:使用位时,* always *使用显式无符号数据类型。 –

回答

2

可以用比特移位代替乘法,或者甚至手动计算的位模式为更好的可读性:

const int32 bMSBNeg = (int32)0xFF000000; 

也可以避免所有这些计算通过构造在上面的三个字节数,然后移下来由8位与除法:

if (pbData != NULL) { 
    i32Num = ((pbData[0] << 24) | (pbData[1] << 16) | (pbData[2] << 8))/256; 
} 

注:移动由8代替除以256将根据标准是实现定义的行为。

+1

您的第一行是超出范围的任务(在解包负值时有几个问题;如果OP想要避免实现定义的行为,那么我们将不得不小心) –

+0

C11标准草案n1570:* 6.5.7按位移位运算符5 E1 >> E2的结果是E1右移E2位的位置。 [...]如果E1具有带符号类型和负值,则结果值由实现定义。* – EOF

+1

@EOF Oops,具有其实现定义行为的讨厌标准让我再次感受到了。我应该用256来代替。 – dasblinkenlight