我正在尝试使用c操纵二进制数。我发现下面的最少代码很奇怪。谁能告诉我“ +”和“ |”有什么区别这里?谢谢!
char next_byte1 = 0b11111111;
char next_byte2 = 0b11110101;
short a = (next_byte1 << 8) | next_byte2;
short b = (next_byte1 << 8) + next_byte2;
printf("a vs b is %d ~ %d.\n", a, b);
它显示:a vs b是-11〜-267,分别是0b11111111 11110101和0b1111111011110101。我对这个结果感到非常困惑。
答案 0 :(得分:7)
您看到的问题是,在进行按位运算之前,next_byte2
被符号扩展为完整的int
,从而“破坏”了高字节。
进行位操作时,最好使用unsigned
类型(实际上是使用unsigned的类型)。普通char
类型可以是(通常是)带符号类型,因此最好避免用于这些用途。
答案 1 :(得分:6)
char
用于二进制/按位算术,因为它具有实现定义的签名,并且可能为负数。通常,对默认的C类型使用stdint.h
。char
进行了签名,则在变量初始化期间,其内部的值最终将以二进制补码转换为-1
。分别发生在next_byte1
和next_byte2
上。int
。因此,您的-1
(0xFF)会变为-1
(0xFFFFFFF),然后再离开班次。0xFFFFFF00
的较大负数时表现出来。|
和+
之间的区别在于后者关心符号,因此,在+
的情况下,您最终将负数加在一起,而在{{1}的情况下}二进制表示形式简单地进行或:运算。您可以通过以下方式修复程序:
|
现在#include <stdio.h>
#include <stdint.h>
int main(void)
{
uint8_t next_byte1 = 0xFF;
uint8_t next_byte2 = 0xF5;
uint16_t a = (next_byte1 << 8) | next_byte2;
uint16_t b = (next_byte1 << 8) + next_byte2;
printf("a vs b is %d ~ %d.\n", a, b);
}
和|
可以按预期工作。
答案 2 :(得分:0)
两个答案都可以解决您的问题。我只想在'|'周围添加清晰度和“ +”运算符。
'|'是按位或运算符
'+'是加法运算符,它转换为包含性OR
CARRY传播的多位数字运算符。
虽然它们在某些情况下可能会产生与您的示例相同的结果,但是它们不是同一运算符,并且通常不应期望得到相同的结果。