Dart 位运算符与移位运算符

操作数字的二进制每一位,仅搭配整数使用

位运算符和移位运算符表

运算符名称运算规则
&按位与 AND对应二进制位同时为 1,结果位才是 1,否则 0
|按位或 OR对应二进制位任意一个为 1,结果位就是 1,否则 0
^按位异或 XOR对应二进制位不相同则为 1,相同则为 0
~expr按位取反(一元运算符)所有二进制位 0 ↔ 1,0 变 1、1 变 0
<<左移 Shift left二进制整体向左移动 N 位,右侧补 0
>>有符号右移 Shift right二进制整体向右移动 N 位,左侧补符号位(正数补 0、负数补 1)
>>>无符号右移 Unsigned shift right二进制整体向右移动 N 位,左侧统一补 0;负数会先转为无符号 32 位整数再移位

按位与运算符(&

两个对应二进制位同时为 1时,结果位为 1;否则结果位为 0。

第一个数字(二进制位)第二个数字(二进制位)运算结果
111
100
010
000

例子

void main() {
  // 单比特位运算验证
  assert((1 & 1) == 1);
  assert((1 & 0) == 0);
  assert((0 & 1) == 0);
  assert((0 & 0) == 0);

  // 多比特整数运算示例
  final a = 0x22; // 二进制 00100010
  final b = 0x0f; // 二进制 00001111
  assert((a & b) == 0x02); // 结果 00000010
}Code language: PHP (php)

按位或运算符(|

两个对应二进制位任意一个为 1时,结果位为 1;否则结果位为 0。

第一个数字(二进制位)第二个数字(二进制位)运算结果
111
101
011
000
void main() {
  // 单比特位运算验证
  assert((1 | 1) == 1);
  assert((1 | 0) == 1);
  assert((0 | 1) == 1);
  assert((0 | 0) == 0);

  // 多比特整数运算示例
  final a = 0x22; // 二进制 00100010
  final b = 0x0f; // 二进制 00001111
  assert((a | b) == 0x2f); // 结果 00101111
}Code language: PHP (php)

按位异或运算符(^

两个对应二进制位数值不同时,结果位为 1;数值相同时结果位为 0。

第一个数字(二进制位)第二个数字(二进制位)运算结果
110
101
011
000

例子

void main() {
  // 单比特位运算验证
  assert((1 ^ 1) == 0);
  assert((1 ^ 0) == 1);
  assert((0 ^ 1) == 1);
  assert((0 ^ 0) == 0);

  // 多比特整数运算示例
  final a = 0x22; // 二进制 00100010
  final b = 0x0f; // 二进制 00001111
  assert((a ^ b) == 0x2d); // 结果 00101101
}Code language: PHP (php)

按位取反运算符(~

一元运算符,仅需 1 个操作数,对二进制位逐位取反:0 变为 1,1 变为 0。

第一个数字(二进制位)运算结果
10
01

例子

void main() {
  // 单比特位运算验证
  assert((~1 & 1) == 0);
  assert((~0 & 1) == 1);

  // 多比特整数运算示例
  final a = 0x22; // 二进制 00100010
  final mask = 0x0f; // 二进制 00001111
  assert((a & ~mask) == 0x20); // 取反mask后与a做与运算,清空低4位
}Code language: PHP (php)

看例子

void main() {
  // 定义测试数值
  final value = 0x22;   // 十六进制 0x22 = 十进制 34,二进制 00100010
  final bitmask = 0x0f; // 十六进制 0x0f = 十进制 15,二进制 00001111

  // 1. 按位与 &
  print('value & bitmask = ${value & bitmask}'); // 0x02 = 2
  assert((value & bitmask) == 0x02);

  // 2. 按位与+取反(& ~mask 常用作清空低位)
  print('value & ~bitmask = ${value & ~bitmask}'); // 0x20 = 32
  assert((value & ~bitmask) == 0x20);

  // 3. 按位或 |
  print('value | bitmask = ${value | bitmask}'); // 0x2f = 47
  assert((value | bitmask) == 0x2f);

  // 4. 按位异或 ^
  print('value ^ bitmask = ${value ^ bitmask}'); // 0x2d = 45
  assert((value ^ bitmask) == 0x2d);

  // 5. 左移 <<
  print('value << 4 = ${value << 4}'); // 0x220 = 544
  assert((value << 4) == 0x220);

  // 6. 有符号右移 >>(正数)
  print('value >> 4 = ${value >> 4}'); // 0x02 = 2
  assert((value >> 4) == 0x02);

  // 7. 有符号右移 >>(负数,跨平台行为差异)
  print('-value >> 4 = ${-value >> 4}'); // -0x03 = -3
  assert((-value >> 4) == -0x03);

  // 8. 无符号右移 >>>(正数,Dart2.14+)
  print('value >>> 4 = ${value >>> 4}'); // 0x02 = 2
  assert((value >>> 4) == 0x02);

  // 9. 无符号右移 >>>(负数,结果一定大于0)
  print('-value >>> 4 = ${-value >>> 4}');
  assert((-value >>> 4) > 0);
}Code language: PHP (php)

执行结果

D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
value & bitmask = 2
value & ~bitmask = 32
value | bitmask = 47
value ^ bitmask = 45
value << 4 = 544
value >> 4 = 2
-value >> 4 = -3
value >>> 4 = 2
-value >>> 4 = 1152921504606846973

以上例子逐个分解

1 按位与
00100010
00001111
--------
00000010

最终结果是 00000010,也就是十进制的 2

2 按位与取反 & ~mask
00100010
11110000  // ~00001111
---------
00100000  // 0x20 = 32Code language: JavaScript (javascript)

以上的11110000 是~mask 00001111取反后的结果 0变1 1变0

3 按位或 |

00100010
00001111
---------
00101111  // 0x2f = 47Code language: JavaScript (javascript)

只要有一个1 结果就算1 ,除非两个都是0,结果才是0

4 按位异或 ^

00100010
00001111
---------
00101101  // 0x2d = 45Code language: JavaScript (javascript)

上下不同,结果才是1,上下相同,结果就是0

5 左移 << 4

00100010 << 4 = 001000100000
结果:0x220 = 544

6 有符号右移 >> 4 (正数)

00100010 >> 4 = 00000010
结果:0x02 = 2

7 有符号右移 >> 4(负数)

-00100010 >> 4 = -00000011
结果:-0x03 = -3

8 无符号右移 >>> 4(正数)

00100010 >>> 4 = 00000010
结果:0x02 = 2

9 无符号右移 >>> 4(负数)

-00100010 >>> 4 = (高位补0)00001101...  // 结果一定大于0Code language: JavaScript (javascript)

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注