位运算符

本文详细介绍了计算机中原码、反码、补码的概念,并通过实例展示了位运算符的使用方法,包括左移、右移、按位与、按位或、按位异或及求反运算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原码:就是二进制定点表示法,即最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。

反码:正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。

补码:正数的补码与其原码相同;负数的补码是在其反码的末位加1。

计算机表示出来的是原码,在内存中参与计算的是补码。

                                                                                                                   位运算符

运算符

运算

范例

<<

左移

3 << 2 = 12 --> 3*2*2=12

>>

右移

3 >> 1 = 1  --> 3/2=1

>>>

无符号右移

3 >>> 1 = 1 --> 3/2=1

&

与运算

6 & 3 = 2

|

或运算

6 | 3 = 7

^

异或运算

6 ^ 3 = 5

~

反码

~6 = -7


1.   按位与运算&

任何二进制位和0进行&运算,结果是0;和1进行&运算结果是原值。(有0则0)

int a=10;
int b=20;
System.out.println(a&b);
 * a=10 的二进制是:00000000 00000000 00000000 00001010
 * b=20 的二进制是:00000000 00000000 00000000 00010100
 * 00000000 00000000 00000000 00001010
 * &
 * 00000000 00000000 00000000 00010100
* -------------------------------------------
*  00000000 00000000 00000000 00000000
*  结果是:0


2.   按位或运算|

任何二进制位和0进行 | 运算,结果是原值;和1进行 | 运算结果是1。(有1则1)
int a=10;
int b=20;
System.out.println(a|b);
	 * a=10 的二进制是:00000000 00000000 00000000 00001010
	 * 
	 * b=20 的二进制是:00000000 00000000 00000000 00010100
	 * 
	 * 00000000 00000000 00000000 00001010
	 * |
	 * 00000000 00000000 00000000 00010100
	 * -------------------------------------------
	 * 00000000 00000000 00000000 00011110
	 * 结果是: 30

3.按位异或运算 ^

任何相同二进制位进行 ^ 运算,结果是0;不相同二进制位 ^ 运算结果是1。(相同则0,不同则1)
	int a=10;
	int b=20;
	System.out.println(a^b);
	 * a=10 的二进制是:00000000 00000000 00000000 00001010
	 * 
	 * b=20 的二进制是:00000000 00000000 00000000 00010100
	 * 
	 * 00000000 00000000 00000000 00001010
	 * ^
	 * 00000000 00000000 00000000 00010100
	 * -------------------------------------------
	 * 00000000 00000000 00000000 00011110
	 * 结果是: 30


4.   求反运算~

二进制位进行 ~ 运算 ,1变0,0变1
int a=10;
System.out.println(~a);
	 * 00000000 00000000 00000000 00001010
	 * ~
	 * -------------------------------------------
	 * 11111111 11111111 11111111 11110101 补码
	 * 11111111 11111111 11111111 11110100 反码
	 * 10000000 00000000 00000000 00001011 原码
	 * 结果是:10


5.   左移运算<<

空位补0,被移除的高位丢弃。

int a=3<<4;
System.out.println(a);
/*把3的二进制位向左移动4位
*          00000000 00000000 00000000 00000011
*  (0000)0000 00000000 00000000 00000011(0000)
* 二进制结果:00110000  转换成十进制结果: 48
int e=-5<<4;
System.out.println(e);
/*把-5向左移动4位
 *     10000000 00000000 00000000 00000101 原码
 *     11111111 11111111 11111111 11111010 反码
 *     11111111 11111111 11111111 11111011 补码
 * 11111111 11111111 11111111 11111011(0000)
 * 1111 11111111 11111111 111110110000  补码
 * 1111 11111111 11111111 111110101111  反码
 * 1000 00000000 00000000 000001010000 原码
 * 十进制结果-80
 */


6.   右移运算>>

被移位的二进制最高位是0,右移后,空缺位补0;最高位是1,最高位补1。
int b=5>>4;
/*把5的二进制位向右移动4位
 * 00000000 00000000 00000000 00000101
 * (0000)00000000 00000000 00000000 0000(0101)
结果是:0

int d=-5>>4;
System.out.println(d);
/*把-5向右移动4位
* 10000000 00000000 00000000 00000101 原码
* 11111111 11111111 11111111 11111010 反码
* 11111111 11111111 11111111 11111011 补码
* 111111111111 11111111 11111111 1111(1011)
* 111111111111 11111111 11111111 1111  补码
* 111111111111 11111111 11111111 1110  反码
* 100000000000 00000000 00000000 0001 原码
* 十进制结果-1
 */

7.   无符号右移>>>

被移位二进制最高位无论是0或者是1,空缺位都用0补。
int b=5>>>4;
/*把5的二进制位向右移动4位
* 00000000 00000000 00000000 00000101
* (0000)00000000 00000000 00000000 0000(0101)
结果是:0
计算出24的二进制:11000   :-24 >>> 2
原码:10000000 00000000 00000000 00011000
反码:11111111 11111111 11111111 11100111
补码:11111111 11111111 11111111 11101000
		
11111111 11111111 11111111 11101000
0011111111 11111111 11111111 111010(00)



<think>好的,用户的问题是关于单片机中的“三位运算符”的使用说明或示例。首先,我需要确认用户是否指的是“三目运算符”或者是否存在其他可能的误解。因为在编程中,常见的位运算符通常是按位与(&)、按位或(|)、按位异或(^)、按位取反(~)、左移(<<)和右移(>>),这些通常被称为位运算符,而“三位运算符”这个术语并不常见,可能是用户输入时的笔误。 接下来,我会考虑用户提到的参考引用内容,其中提到了位运算符的种类,如左移、右移、按位取反等。用户可能将“三目运算符”误写为“三位运算符”,或者可能是指三个位的操作。但根据常见的编程知识,三目运算符(条件运算符)是存在的,形式为条件 ? 表达式1 : 表达式2,用于条件判断。而位运算符中并没有三位的运算符,因此需要进一步澄清。 然后,我需要检查单片机编程中常用的运算符。在C语言中,单片机常用的位运算符是上述提到的那些,每个运算符处理的是单个位或多个位的组合。例如,按位与用于屏蔽某些位,按位或用于设置某些位,移位运算用于乘以或除以2的幂次方。用户可能想了解如何使用这些位运算符进行三位的操作,比如同时操作三个位,或者处理三位的数据。 另外,用户可能是在问三目运算符在单片机中的应用,比如条件判断的简洁写法。但根据用户的引用内容,他们之前的问题是关于位运算符的,所以更可能是在询问位运算符相关的三位操作。例如,如何用位运算符提取或设置三个连续的位。 考虑到用户可能的混淆,回答中需要先澄清可能的术语误解,然后分别解释三目运算符和位运算符中的三位操作。同时,需要提供具体的示例代码,说明在单片机编程中如何应用这些运算符,比如寄存器操作中的位掩码设置、状态标志的读取或修改等。 最后,生成相关问题,帮助用户进一步理解相关概念,比如三目运算符与if语句的区别、位运算优化技巧等。</think>[系统级回答] 关于单片机编程中"三位运算符"的说明如下: 1. 术语澄清: "三位运算符"实际为术语混淆,可能指以下两种运算符: - 三目运算符(条件运算符):唯一的三操作数运算符$条件 ? 真值表达式 : 假值表达式$ - 位运算符:处理二进制位的运算符,如$&, |, ^, ~, <<, >>$等[^1] 2. 三目运算符示例: ```c // 设置GPIO输出电平 GPIO_PIN = (电压 > 2.5V) ? HIGH : LOW; // 计算PWM占空比 uint8_t duty_cycle = (温度 > 30) ? 75 : 50; ``` 3. 位运算符的三位操作: ```c // 定义3位状态寄存器(假设使用低3位) #define STATE_MASK 0x07 // 二进制00000111 // 设置后三位状态 PORT |= (new_state & STATE_MASK); // 保留其他位,设置低3位 // 读取中间三位(假设位3-5) uint8_t sensor_val = (ADC_DATA >> 3) & 0x07; // 三位置换操作 value = (value & 0xF8) | (new_bits & 0x07); // 保持高5位不变,替换低3位 ``` 4. 复合位运算示例: ```c // LED阵列控制(假设每3位控制一组RGB LED) uint32_t led_ctrl = 0; led_ctrl |= (red << 0) | (green << 1) | (blue << 2); // 设置第一组颜色 led_ctrl |= (模式 ? 0x38 : 0x07) << 3; // 根据模式设置第二组颜色 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值