Saravanan
Saravanan

Reputation: 11592

Why do we need to use shift operators in java?

  1. What is the purpose of using Shift operators rather than using division and multiplication?

  2. Are there any other benefits of using shift operators?

  3. Where should one try to use the shift operator?

Upvotes: 23

Views: 13873

Answers (6)

Alessandro
Alessandro

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

Nikhil Kumar
Nikhil Kumar

Reputation: 2896

Strength reduction occurs when an operation is replaced by an equivalent operation that executes faster.

  1. replacing integer division or multiplication by a power of 2 with an arithmetic shift or logical shift..
  2. replacing integer multiplication by a constant with a combination of shifts, adds or subtracts.
  3. replacing integer division by a constant with a multiplication, taking advantage of the limited range of machine integers.

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

  1. Improves performance.
  2. Faster calculations.

Demerit

  1. Readability of Code decreases.

Upvotes: 1

Charles Goodwin
Charles Goodwin

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 string
  • 0xAAAARRRRGGGGBBBB as an integer

In 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

Muhammad Hewedy
Muhammad Hewedy

Reputation: 30058

It might also used in encryption/decryption .. Example: http://freedom2blog.com/2010/05/easy-encryption-using-bitwise-exclusive-or-xor/

Upvotes: 1

Bohemian
Bohemian

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

Sean Owen
Sean Owen

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

Related Questions