sar和>>都是右移操作,其区别简而言之前者保留符号位,后者不保留。要解释清楚这个问题,需要从有符号数和无符号数讲起:
有符号数和无符号数
打个比方int8和uint8
-
uint8(无符号 8 位整数)
- 取值范围:0 ~ 255
- 最高位只是数值的一部分,没有符号意义
-
int8(有符号 8 位整数)
- 取值范围:-128 ~ 127
- 最高位(第 8 位)是符号位:0 表示正数,1 表示负数
这二者的取值范围是由交集的也就是0~ 127,在这个范围内其而二进制表示是完全相同的。
但是当最高位变成1时,则有所不同:
打个比方一个有符号整数-5的二进制表示步骤如下:
- 先写出 5 的二进制:0000 0101
- 取反:1111 1010
- 加1:1111 1011
-5 在 int8
中二进制表示就是1111 1011
而同样的二进制表示如果是无符号整数则代表251
区别总结
到这里sar和>>的区别就显而易见了:
操作 | 适用类型 | 名称 | 高位补什么 | 能否保留符号 | 典型用途 |
---|---|---|---|---|---|
sar(n,value) | 有符号整数 | 算术右移 | 补符号位(0或1) | 是 | int128/int256 等有符号数的右移、提取高位 |
value >> n | 无符号整数 | 逻辑右移 | 补0 | 否 | uint128/uint256 等无符号数的右移 |
打个比方:
原始值 | 二进制 | 适用右移方案 | 逻辑右移2位(>>) | 结果 |
---|---|---|---|---|
-5(int8) | 11111011 | sar | 11111110 | -2 |
251(int8) | 11111011 | >> | 00111110 | 62 |
所有当遇到有符号整数需要保留符号位的时候使用sar操作,否则使用>>