为什么我们需要在java中使用移位运算符?

时间:2011-09-17 12:10:06

标签: java bit-shift

  1. 使用Shift运算符而不是使用除法和乘法的目的是什么?

  2. 使用移位运营商还有其他好处吗?

  3. 应该在哪里尝试使用移位运算符?

6 个答案:

答案 0 :(得分:13)

除法和乘法不是真正使用位移运算符。他们是一个过时的'优化',有些人喜欢申请。

它们是位操作,在整数值内的位级工作时完全是必需的。

例如,假设我有两个字节是两字节(16位)无符号值的高阶和低阶字节。假设您需要构建该值。在Java中,那是:

int high = ...;
int low = ...;
int twoByteValue = (high << 8) | low;

如果没有班次操作员,你无法做到这一点。

回答您的问题:您可以在需要使用它们的地方使用它们!而在其他任何地方。

答案 1 :(得分:6)

当您执行逻辑位操作时使用移位运算符,而不是数学操作。

可以用于速度,在处理2的幂的操作数时明显快于除法/乘法,但代码的清晰度通常优于原始速度。

答案 2 :(得分:1)

答案 3 :(得分:1)

它可用于构造数字组合的值,其中位自身被分组为不同的值。 (肖恩欧文的回答更好地解释了这一点。)

例如,使用以下颜色:

  • "#AARRGGBB"作为base16字符串
  • 0xAAAARRRRGGGGBBBB为整数

在整数格式中,您可以使用shift将整数分量的实际值作为可用数字。

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;
}

答案 4 :(得分:0)

当操作被更快执行的等效操作替换时,会发生强度降低。

  1. 用算术移位或逻辑移位替换整数除法或乘以2的幂。
  2. 使用移位,加法或减法的组合将整数乘法替换为常量。
  3. 利用有限的机器整数范围,用乘法替换整数除法。
  4. 为什么这是错的?

    1.随着计算所需时间的增加,降低性能。 2.算术分割和乘法等操作较慢。 3.昂贵的操作

    优势

    1. 提高表现。
    2. 更快的计算。
    3. 记过

      1. 代码的可读性下降。

答案 5 :(得分:0)

在处理标志时很有用,你可以在一个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)。