位运算符

位运算一览表

符号示例含义
&$a & $b按位与。将 $a 和 $b 中都为 1 的位设为 1
|$a | $b按位或。将 $a 和 $b 中任何一个为 1 的位设为 1
^$a ^ $c按位异或。将 $a 和 $b 中相同位不一致的位设为 1
~$a~$a按位取反。将 $a 为 1 的位设为 0,为 0 的位设为 1
<<$a << $c左移。将 $a 的位向 移动 $b 次
>>$d >> $b左移。将 $a 的位向 移动 $b 次

& 运算符

按位与。相同为 1,不同为 0

$a = 1; // 0001
$b = 2; // 0010
echo $a & $b; // 0000

按位比较,相同位得1,不同位得 0。由于 1 和 2 的二进制数中每个位都不相同,所以结果为: 0000,也就是 0。

| 运算符

按位或。有 1 为 1,无 1 为 0

$a = 1; // 0001
$b = 3; // 0011
echo $a | $b; // 0011

按位比较,相同位得 0 ,不同位 得 1,所以结果为: 0011,也就是 3。

^ 运算符

按位异或。相同为 0,不同为 1

$a = 1; // 0001
$b = 3; // 0011
echo $a ^ $b; // 0010

按位比较,相同位得 0 ,不同位 得 1,所以结果为: 0010,也就是 2。

~ 运算符

按位取反。1 取 0,0 取 1

$a = 1; // 0000 0000 0000 0000 0000 0000 0000 0001
$a1 = ~$a;
echo $a1; // -2。 

这个运算符相比较其它位运算符要复杂一些。我们知道,大多数编程语言中,最高位是符号位,那么,32 位操作系统下,PHP 整数的最大值是:

0111 1111 1111 1111 1111 1111 1111 1111 = 2147483647

因此,当对 1 进行按位取反后,得到

$A1 = 1111 1111 1111 1111 1111 1111 1111 1110

符号位为 1,即为 负数。在计算机中,负数以其对应绝对值的补码形式表达。也就是说,$a1 的补码是 $A1,则

反码 = 补码 - 1 = 1111 1111 1111 1111 1111 1111 1111 1101

那么 $a1 对应的整数就是:

原码 = 反码各位取反 = 0000 0000 0000 0000 0000 0000 0000 0010 = -2;

<< 运算符

各位向左移动,末尾补 0

$a = 2; // 0000 0000 0000 0000 0000 0000 0000 0010
$a1 = $a << 3;
echo $a1; // 16

32 位系统下,一个整数用 32 位表示。当位数向左移动,舍去多余的位数,末尾补 0 ,则得到 $a1 为:

0000 0000 0000 0000 0000 0000 0001 0000 = 16

因此

$a << $b = a ( a^( a(b+1) // a 的 ( a 的 ( a(b + 1) 次方

左移运算符有一个比较有趣的地方,当一个数向左移动超过计算机指定整数位时,就会出现不符合我们上述总结的原数平方规则的情况。比如 2 在 64 位系统下,向左移动 62、63、64 位:

echo 2 >> 61 // 4611686018427387904
echo 2 >> 62 // -9223372036854775808
echo 2 >> 63 // 0
echo 2 >> 64 // 0

有兴趣的朋友可以列出对应二进制数,推演下计算过程。

>> 运算符

各位向右移动,前面补 0

$a = 8; // 0000 0000 0000 0000 0000 0000 0000 1000
$a1 = $a << 3;
echo $a1; // 16

左移和右移运算符“误区”

关于左移和右移运算符,很多朋友可能会看到这样的总结:

左移平方,右移开方

其实严格来说,这只针对值为 2 的正整数次幂的整数有效。当不是 2 的正整数次幂时,比如:

$a = 9; // 0000 0000 0000 0000 0000 0000 0000 1001
$a1 = $a >> 1;
echo $a1; // 4

所以,遇到左移和右移运算符时,要实际情况实际分析,不能一味的按照别人的总结走。

<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、付费专栏及课程。

余额充值