二进制位运算练习

编程

复习一下二进制中的位运算,写些单元测试练习一下

import java.util.Arrays;

import org.junit.Assert;

import org.junit.Test;

/**

* 位运算测试

*/

public class BitCalc {

/**

* 异或运算 ^ </br>

* 运算规则:相同为0,不同为1

*/

@Test

public void testXor() {

// int long 同理

byte a = "a";

System.out.println("a = " + a);

byte b = "b";

System.out.println("b = " + b);

int c = a ^ b;

System.out.println("c = a ^ b = " + c);

System.out.println("c ^ a = " + (c ^ a));

System.out.println("c ^ b = " + (c ^ b));

Assert.assertTrue((c ^ a) == b);

Assert.assertTrue((c ^ b) == a);

// a与b交换

a ^= b;

b ^= a;

a ^= b;

System.out.println("a = " + a);

System.out.println("b = " + b);

Assert.assertTrue((a ^ b) == c);

int source = -14;

int s = ~source + 1;// 求相反数,原理同求补码:反码+1,等效于(source ^ -1) + 1 和

// ~(source-1)

Assert.assertTrue(s == -source);

int x = a;

x = a ^ b ^ x;

}

/**

* 与运算 & </br>

* 运算规则:都为1时为1,其他为0

*/

@Test

public void testAnd() {

byte a = 1 & 1;

Assert.assertTrue(a == 1);

int count = 100000;

Assert.assertTrue((count & 1) == (count % 2));

// 取模运算转化成位运算 (在不产生溢出的情况下) a % (2^n) 等价于 a & (2^n - 1)

for (int i = 1; i < count; i++) {

for (int j = 2; j < 10; j++) {

if (i % (2 << j) == 0) {

Assert.assertTrue((i & ((2 << j) - 1)) == 0);

}

if ((i & ((2 << j) - 1)) == 0) {

Assert.assertTrue((i % (2 << j) == 0));

}

}

}

}

/**

* 右移运算 >> </br>

* 运算规则:将二进制字节右移n位,高位补符号位,低位丢弃

*/

@Test

public void testShiftRight() {

int a = 8 >> 3;

Assert.assertTrue(a == 8 / (2 * 2 * 2));

// (byte) 256=0

System.out.println((byte) 256);

// =》-1

System.out.println((byte) (-5 >> 8 & 0xFF));

// int转byte

int sum = -128;

System.out.println(Integer.toBinaryString(sum));

// int点4个字节

byte[] intByte = new byte[4];

for (int i = 0; i < 4; i++) {

int n = (3 - i) * 8;

// & 0xFF取低8位,好像不需要& 0xFF,强制转换成byte,只取了后8位,前24位丢弃了

intByte[i] = (byte) (sum >> n & 0xFF);

}

System.out.println(Arrays.toString(intByte));

System.out.println(abs(-5));

}

/**

* 计算绝对值

*/

private static int abs(int x) {

int y;

y = x >> 31;

return (x + y) ^ y; // 补码转原码算法

}

/**

* 左移运算 << </br>

* 运算规则:将二进制字节左移n位,低位补0,高位丢弃

*/

@Test

public void testShiftLeft() {

int a = 8 << 3;

Assert.assertTrue(a == 8 * (2 * 2 * 2));

// byte转int

// 11111111 11111111 11111111 11111111=-1

byte[] intByte = new byte[] { -1, -1, -1, -1 };

// =》11111111 00000000=-256

System.out.println(intByte[0] << 8);

// =》00000000 00000000 11111111 00000000=65280

System.out.println(intByte[0] & 0xFF << 8);

int sum = 0;

for (int i = 0; i < 4; i++) {

int n = (3 - i) * 8;

// & 0xFF补零扩充到32位

sum += intByte[i] & 0xFF << n;

}

System.out.println(sum);

System.out.println(Integer.toBinaryString(sum));

// new byte[] { 1, 2, 3, 4 }

System.out.println(Integer.valueOf("00000001000000100000001100000100", 2));

}

/**

* 求平均数 </br>

* @see

* x|y = x&y + x^y </br>

* </br>

* x|y原理:可以理解成同时为1的部分(x&y),加上不同时不1的部分(x^y)</br>

* </br>

* x+y = 2(x&y) + x^y </br>

* x+y = x|y + x&y </br>

* </br>

* x+y原理:把x和y分别拆开成两部分,将4个部分相加</br>

* 第一部分为x和y的二进制码中同时为1的部分(也就是x&y),</br>

* 第二部分为剩下的一个是1,一个是0,或是两个都是0(也就是x|y)</br>

*

*/

@Test

public void average() {

int x = Integer.MAX_VALUE;

int y = Integer.MAX_VALUE - 1;

// int z = (x + y) / 2; =-2,溢出

System.out.println(((x & 1) + (y & 1)) / 2);

System.out.println(x / 2 + y / 2 + ((x & 1) + (y & 1)) / 2);

int z = (x & y) + ((x ^ y) >> 1);

System.out.println(z);

z = (x >> 1) + (y >> 1) + (((x & 1) + (y & 1)) >> 1);

System.out.println(z);

}

/**

* 位操作进行二进制逆序 </br>

* 数34520的二进制表示: 10000110 11011000</br>

* 逆序后则为: 00011011 01100001 它的十进制为7009

*/

@Test

public void oppsiteOrder() {

short a = (short) 34520;

System.out.println(Integer.toBinaryString(a & 0xFFFF));

//前8位与后8位对换

a = (short) ((a >> 8 & 0x00FF | a << 8 & 0xFF00));

System.out.println(Integer.toBinaryString(a & 0xFFFF));

//前后8位中的4位相互对换

a = (short) ((a >> 4 & 0x0F0F | a << 4 & 0xF0F0));

System.out.println(Integer.toBinaryString(a & 0xFFFF));

//每相邻2位相互对换

a = (short) ((a >> 2 & 0x3333 | a << 2 & 0xCCCC));

System.out.println(Integer.toBinaryString(a & 0xFFFF));

//每相邻1位相互对换

a = (short) ((a >> 1 & 0x5555 | a << 1 & 0xAAAA));

System.out.println(Integer.toBinaryString(a & 0xFFFF));

String str = "123456789";

byte[] strBytes = str.getBytes();

for (int i = 0, len = strBytes.length; i < len / 2; i++) {

strBytes[i] ^= strBytes[len - i - 1];

strBytes[len - i - 1] ^= strBytes[i];

strBytes[i] ^= strBytes[len - i - 1];

}

// 987654321,不适合包含中文的字符串

System.out.println(new String(strBytes));

}

}

参考:

https://www.zhihu.com/question/38206659

https://blog.csdn.net/black_OX/article/details/46411997

以上是 二进制位运算练习 的全部内容, 来源链接: utcz.com/z/518172.html

回到顶部