在Java中对数据的运算,有很好的规范支持,尤其是针对二进制的位运算,解决了C/C++ 逻辑右移 于 算术右移的不确定性,几乎所有市面上见到的C/C++编译器都只对有符号数使用算术右移,Java在这方面作的比C/C++出色。
这里我用一个经典的1,-1的移位运算码来展示:
package com.opencfg.test; /** * Integer Binary Test * * @author opencfg.com * @version */ public class Test { final static char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; public static void log(final String message) { System.out.println(message); } /** * 这里扩展了JDK开源代码里自带的private方法toUnsignedString ,打印出0字符 * * @param i * @param shift * @return */ public static String toUnsignedStringEx(int i, int shift) { char[] buf = new char[Integer.SIZE]; int charPos = Integer.SIZE; int radix = 1 << shift; for(int mask = radix - 1, count = Integer.SIZE; i != 0 || count > 0; i >>>= shift, count--) { buf[--charPos] = digits[i & mask]; } return new String(buf, charPos, (Integer.SIZE - charPos)); } public static void main(String[] args) { // 1111 1111 1111 1111 1111 1111 1111 1111 int a = -1; // 0000 0000 0000 0000 0000 0000 0000 0001 int b = 1; log("int size: " + Integer.SIZE); log("a : " + toUnsignedStringEx(a, 1)); log("b : " + toUnsignedStringEx(b, 1)); log("a << 3 : " + toUnsignedStringEx((a << 3), 1)); log("b << 3 : " + toUnsignedStringEx((b << 3), 1)); log("a << 35 : " + toUnsignedStringEx((a << 35), 1)); log("b << 35 : " + toUnsignedStringEx((b << 35), 1)); log("a >> 3 : " + toUnsignedStringEx((a >> 3), 1)); log("b >> 3 : " + toUnsignedStringEx((b >> 3), 1)); log("a >> 35 : " + toUnsignedStringEx((a >> 35), 1)); log("b >> 35 : " + toUnsignedStringEx((b >> 35), 1)); log("a >>> 3 : " + toUnsignedStringEx((a >>> 3), 1)); log("b >>> 3 : " + toUnsignedStringEx((b >>> 3), 1)); log("a >>> 35: " + toUnsignedStringEx((a >>> 35), 1)); log("b >>> 35: " + toUnsignedStringEx((b >>> 35), 1)); } }
执行结果如下:
int size: 32 a : 11111111111111111111111111111111 b : 00000000000000000000000000000001 a << 3 : 11111111111111111111111111111000 b << 3 : 00000000000000000000000000001000 a << 35 : 11111111111111111111111111111000 b << 35 : 00000000000000000000000000001000 a >> 3 : 11111111111111111111111111111111 b >> 3 : 00000000000000000000000000000000 a >> 35 : 11111111111111111111111111111111 b >> 35 : 00000000000000000000000000000000 a >>> 3 : 00011111111111111111111111111111 b >>> 3 : 00000000000000000000000000000000 a >>> 35: 00011111111111111111111111111111 b >>> 35: 00000000000000000000000000000000
计算机存储数字是以二进制补码表示, 逻辑右移 (>>>) 将高位补0,低位顺序移出, 算术右移(>>) 将延续高位的符号位,负数补1,整数补0, 低位顺序移出。
Java中关键的标准在 ,对于一个由w位组成的数据类型, 如果要移动 k >=w 位时, 会采用 k mod w 来作标准移位。
这对于一些C/C++ 编译器来说很难做到。
从一些很小的语言细节,不难看出sun公司的风格,的确是那句经典的一流公司作标准,二流公司作应用。