Reputation: 11592
What is the purpose of using Shift operators rather than using division and multiplication?
Are there any other benefits of using shift operators?
Where should one try to use the shift operator?
Upvotes: 23
Views: 13873
Reputation: 4472
It is useful when you deal with flags, you could store in just one int
variable the information about active flags, see following please:
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);
}
}
The above example prints the follow to the output:
128: off
64: off
32: off
16: off
8: on
4: off
2: on
1: off
As you can see, the active_flags
are number 2 and number 8. We stored that information in just one variable, its value is 10 (8+2).
Upvotes: 1
Reputation: 2896
Strength reduction occurs when an operation is replaced by an equivalent operation that executes faster.
Why is this wrong?
1.Reduces performance as time required for calculation increases. 2. Arithmetic Operations like division and multiplication are slower. 3. Expensive operations
Benefits
Demerit
Upvotes: 1
Reputation: 6642
It is useful in constructing values which are a combination of numbers, where bits are grouped as different values themselves. (Sean Owen's answer explains this better.)
For example, working with colours which are:
"#AARRGGBB"
as a base16 string0xAAAARRRRGGGGBBBB
as an integerIn its integer format, you can use shift to get the actual value of a component of the integer as a usable number.
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;
}
Upvotes: 2
Reputation: 30058
It might also used in encryption/decryption .. Example: http://freedom2blog.com/2010/05/easy-encryption-using-bitwise-exclusive-or-xor/
Upvotes: 1
Reputation: 424983
The shift operator is used when you're performing logical bits operations, as opposed to mathematical operations.
It can be used for speed, being significantly faster than division/multiplication when dealing with operands that are powers of two, but clarity of code is usually preferred over raw speed.
Upvotes: 10
Reputation: 66876
Division and multiplication are not really a use of bit-shift operators. They're an outdated 'optimization' some like to apply.
They are bit operations, and completely necessary when working at the level of bits within an integer value.
For example, say I have two bytes that are the high-order and low-order bytes of a two-byte (16-bit) unsigned value. Say you need to construct that value. In Java, that's:
int high = ...;
int low = ...;
int twoByteValue = (high << 8) | low;
You couldn't otherwise do this without a shift operator.
To answer your questions: you use them where you need to use them! and nowhere else.
Upvotes: 17