ビット演算のいくつかのアプリケーション(Blue Bridge College)
参照
1つの知識を補足する
1.正数的源码是他的反码和补码
2.负数的反码是将他源码除符号位进行按位取反
3.负数的补码是将他反码加1得到的
//后面的运算都建立在补码之上
4.按位与 & : 两个相应的二进制对应,同为1是1,否则为0
5.按位或 | :有1为1,否则为0
6.异或 ^ : 相同为零, 否则为1
7.<<: 左移运算, 右边空出的位用0填补, 高位左移溢出则舍弃该高位
8.>>:右移运算, 左边空出的位,正数用0填补,负数用1填补。注:不同的环境填补方式可能不同;低位右移溢出则舍弃该位。
9.>>> : 无符号右移, 正数与右移规则一样,负数的无符号右移,就是相应的补码移位所得,在高位补0即可
1.奇数か偶数かを判断します
ここではビット単位のANDが使用され、ビット単位のANDと1の前の数値はすべて0であり、最後の数値が1と同じ場合は奇数(ビット単位のANDの値は1)、最後の数値は奇数です。数値があなたとは異なり、偶数です(ビット単位のANDの値は0です)
import java.util.Scanner;
public class Hello {
public static void main(String[] args) {
//判断一个数是奇数还是偶数
Scanner sc = new Scanner(System.in);
System.out.println("输入一个数");
while(true) {
int a = sc.nextInt();
System.out.println(a + "是:" + (((a & 1) == 0) ? "偶数" : "奇数"));
}
}
}
次に、2進数の数値を決定します
同じように、ここではビットごとのAND手法が使用されます
import java.util.Scanner;
public class Hello {
public static void main(String[] args) {
//获取二进制位是0还是1,这里指的是补码
Scanner sc = new Scanner(System.in);
System.out.println("输入一个数");
while(true) {
int a = sc.nextInt();
System.out.println(a + "第5个二进制位是:" + ((((a>>4) & 1) == 0)?0:1));//这里取第5个(从右往左)
}
}
}
3、2つの番号を交換します
ここでは、少し知識を理解する必要があります。排他的論理和は0であり、排他的論理和は1です。
import java.util.Scanner;
public class Hello {
public static void main(String[] args) {
//使用异或技巧交换两个数
Scanner sc = new Scanner(System.in);
System.out.println("输入两个数");
while(true) {
int a = sc.nextInt();
int b = sc.nextInt();
a = a ^ b;
b = a ^ b;//把上面的东西带进去, b^b为0, a^0为a
a = a ^ b;//把上面的东西带进去, a^a为0, b^0为b
System.out.println(a + " " + b);
}
}
}
4、数の絶対値を見つける
//考える:数値は最初にその符号を右にシフトし、符号をすべての位置にシフトしてから、それ自体と排他的論理和演算を実行します。正の数の補数は変更されず、負の数の補数は次のようになります。反転と同等
//最後に1つ追加しますが、この時点では符号ビットのみが変更されています。これは、元のコードを補数に変換するという考え方と同じです。元のコードを2回変換してみると、元の状態に戻ります。
import java.util.Scanner;
public class Hello {
public static void main(String[] args) {
//求绝对值
Scanner sc = new Scanner(System.in);
System.out.println("输入一个数");
while(true) {
int a = sc.nextInt();
System.out.println((a ^ (a>>31)) + (a>>>31));//注意区分无符号移动和有符号移动
}
}
}