使用移位运算符的目的是什么,而不是使用除法和乘法?
使用移位运算符还有其他好处吗?
在什么情况下应该尝试使用移位运算符?
除法和乘法并不是真正使用位移操作符。它们是一种过时的“优化”方式,一些人喜欢应用。
它们是位运算,在操作整数值的位级别时是完全必要的。
例如,假设我有两个字节,它们是无符号16位值的高位字节和低位字节。假设您需要构建该值。在Java中,可以这样实现:
int high = ...;
int low = ...;
int twoByteValue = (high << 8) | low;
如果没有位移运算符,你无法做到这一点。
回答你的问题:你在需要使用它们的地方使用它们!其他地方不用。
移位运算符用于执行逻辑位操作,而不是数学运算。
当处理的操作数是2的幂时,它可以用于加速,比除法/乘法快得多,但通常清晰的代码优先于原始速度。
它在构建数字组合的值时非常有用,其中位被分组为不同的值本身。 (Sean Owen的答案更好地解释了这一点。)
例如,使用颜色:
"#AARRGGBB"
作为base16字符串0xAAAARRRRGGGGBBBB
作为整数在其整数格式中,您可以使用移位来获取整数组件的实际值作为可用数字。
public static int stringToColor(String s) throws JSExn {
// string starts with '#' - parse integer from string
try {
// used to build up the return value
int a, r, g, b;
switch (s.length()) {
case 4:
a = 0xFF000000;
r = Integer.parseInt(s.substring(1, 2), 16);
r = r << 16 | r << 20;
b = Integer.parseInt(s.substring(2, 3), 16);
b = b << 8 | b << 12;
g = Integer.parseInt(s.substring(3, 4), 16);
g = g | g << 4;
break;
case 5:
a = Integer.parseInt(s.substring(1, 2), 16);
a = a << 24 | a << 28;
r = Integer.parseInt(s.substring(2, 3), 16);
r = r << 16 | r << 20;
b = Integer.parseInt(s.substring(3, 4), 16);
b = b << 8 | b << 12;
g = Integer.parseInt(s.substring(4, 5), 16);
g = g | g << 4;
break;
case 7:
a = 0xFF000000;
r = Integer.parseInt(s.substring(1, 3), 16) << 16;
b = Integer.parseInt(s.substring(3, 5), 16) << 8;
g = Integer.parseInt(s.substring(5, 7), 16);
break;
case 9:
a = Integer.parseInt(s.substring(1, 3), 16) << 24;
r = Integer.parseInt(s.substring(3, 5), 16) << 16;
b = Integer.parseInt(s.substring(5, 7), 16) << 8;
g = Integer.parseInt(s.substring(7, 9), 16);
break;
default:
throw new JSExn("Not a valid color: '"+s+"'");
}
// return our integer ARGB
return a | r | b | g;
}
当你处理标志时,将信息存储在一个 int
变量中非常有用,如下所示:
public class DealingWithShiftOperators {
public static void main(String[] args) {
int active_flags = 10;
printActiveFlags(active_flags);
}
public static void printActiveFlags(int active_flags) {
final int TOTAL_FLAGS = 8;
final int MAX_VALUE = 1 << TOTAL_FLAGS;
final int MIN_VALUE = 1;
int current_flag = MAX_VALUE;
do {
current_flag = current_flag >> 1;
if (active_flags - current_flag < 0) {
System.out.println(current_flag + ": off");
} else {
active_flags = active_flags - current_flag;
System.out.println(current_flag + ": on");
}
} while (current_flag > MIN_VALUE);
}
}
128: off
64: off
32: off
16: off
8: on
4: off
2: on
1: off
active_flags
是数字2和数字8。我们仅使用一个变量来存储这些信息,其值为10(8+2)。当一个操作被替换为执行速度更快的等效操作时,就会发生强度降低。
为什么这是错误的?
1. 计算所需的时间增加,降低了性能。 2. 算术运算(如除法和乘法)较慢。 3. 操作开销大。
好处
缺点