目录
|、&、||、&&、^符号含义
|和&为计算机中二进制之间的位运算
在计算机中二进制的0表示false,1表示true。
|为位运算中的或运算:它的运算逻辑为一真则真,全假则假
&为位运算中的并运算:它的运算逻辑为一假则假,全真则真
||和&&为计算机中的逻辑运算符
||表示为或运算:它的运算逻辑为只要一个为true则结果为true
&&表示为并运算:它的运算逻辑为全为true时结果才为true,类似于and,只有两边结果都为true时,最后结果才为true
^为计算机中的异或运算
int x=1;
int y=2;
x^=y;//异或运算,相同为0不同为1。结果为3.
System.out.println("x="+ ++x);
二进制运算过程:
0 0 0 1
0 0 1 0
--------------
0 0 1 1
最后在执行++x,所以最后输出为4。
Java中打印二进制
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
System.out.println("Java二进制-7: "+Integer.toBinaryString(7));
System.out.println("Java二进制-7: "+Integer.toBinaryString(-7));
}
}
Java二进制-7: 111
Java二进制-7: 11111111111111111111111111111001
其他进制打印
public class Main {
public static void main(String[] args) {
System.out.println(Integer.toString(45,3));//45是十进制数,3是多少进制
}
}
负数的二进制(即正数的补码)
先举个正确的例子:
7的二进制形式可以表示如下:
00000000 00000000 00000000 00000111
-7的二进制形式可以表示如下:
11111111 11111111 11111111 11111001
1)左边为高位,右边为低位;
2)最高位为符号位,正数的符号位为0,负数的符号位为1;
3)按照我们正常的逻辑很容易想到只需要把正数7的二进制形式的符号位换成1,-7的二进制表示形式应该是
10000000 00000000 00000000 00000111
但它只是一个原码,不是最终表示形式,所以是不对的;
4)在计算机中,负数以原码的补码形式表达。要想正确推出负数的二进制表示形式,需要先了解以下基本概念
基本概念
一个正数,按照其本身大小转换成的二进制数,称为原码
一个负数,按照其绝对值大小转换成的二进制数,最高位补1,称为原码
比如:
00000000 00000000 00000000 00000111 // 是7的原码
10000000 00000000 00000000 00000111 // 是-7的原码
正数的反码与原码相同
负数的反码为对该数的原码除符号位外各位取反
比如:
00000000 00000000 00000000 00000111 // 是7的反码,和原码相同
10000000 00000000 00000000 00000111 // 是-7的原码
11111111 11111111 11111111 11111000 // 对-7的原码取反(除符号位),即得到了-7的反码
- 1
- 2
- 3
正数的补码与原码相同
负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1;即对负数的补码为对该数的反码的最后一位加1
比如:
00000000 00000000 00000000 00000111 // 是7的补码,和原码相同
10000000 00000000 00000000 00000111 // 是-7的原码
11111111 11111111 11111111 11111000 // 对-7的原码取反(除符号位),即得到了-7的反码
11111111 11111111 11111111 11111001 // 最后一位加1,即得到-7的补码,这也是负数在计算机中最终的表示形式
Java中的>>和>>>
'>>' 算术右移,向右移左边补符号位
'>>>' 逻辑右移,向右移左边补0
System.out.println("Java二进制-7: "+Integer.toBinaryString(-7));
System.out.println("-7>>2: "+Integer.toBinaryString(-7>>2));
System.out.println("-7>>>2: "+Integer.toBinaryString(-7>>>2));
输出:
Java二进制-7: 11111111111111111111111111111001
-7>>2: 11111111111111111111111111111110
-7>>>2: 111111111111111111111111111110 //正常应该这样(00)111111111111111111111111111110左边的两个0不显示
如何找数组中唯一成对的那个数
import java.sql.Array;
import java.util.Arrays;
import java.util.Random;
public class Main {
public static void main(String[] args) {
int N=11;
int[] arr=new int[N];
for(int i=0;i<arr.length-1;i++){
arr[i]=i+1;
}
arr[arr.length-1]=new Random().nextInt(N-1)+1;
int index=new Random().nextInt(N);
int t=arr[arr.length-1];
arr[arr.length-1]=arr[index];
arr[index]=t;
System.out.println(Arrays.toString(arr));
int x1=0;
for(int i=1;i<=N-1;i++){
x1=(x1^i);
}
for(int i=0;i<N;i++){
x1=x1^arr[i];
}
System.out.println(x1);
}
}
二进制中1的个数
1.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int N=sc.nextInt();
System.out.println(Integer.toString(N,2));//打印几进制
int count=0;
for(int i=0;i<32;i++){
if((N&1<<i)==(1<<i)){
count++;
}
}
System.out.println(count);
}
}
2.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int N=sc.nextInt();
System.out.println(Integer.toString(N,2));//打印几进制
int count=0;
while(N!=0){
N=(N-1)&N;
count++;
}
System.out.println(count);
}
}
3.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n= sc.nextInt();
while(n-->0){
int k= sc.nextInt();
int cnt=0;
while(k!=0){
k=k&(k-1);
cnt++;
}
System.out.print(cnt);
if(n!=0) System.out.print(" ");
}
}
}
用一句整数判断一个整数是不是2的整数次方
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int N=sc.nextInt();
System.out.println(Integer.toString(N,2));//打印几进制
int count=0;
while(N!=0){
N=(N-1)&N;
count++;
}
if(count==1) System.out.println("yes");
else System.out.println("no");
//System.out.println(count);
}
}
将整数的奇偶位互换
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
//int a = 0b010000000_00000000_00000000_00000000; 测试边界是否满足
Scanner sc=new Scanner(System.in);
int a = sc.nextInt();
System.out.println("交换前整数:"+a);
System.out.println("交换前整数二进制:"+Integer.toString(a,2));
int b = m(a);
System.out.println("交换后整数:"+b);
System.out.println("交换后整数二进制:"+Integer.toString(b,2));
}
private static int m(int i) {
int ji = i & 0x55555555; //和0101 0101 0101 .。。。。 做与运算保留奇数位 相当于取出
int ou = i & 0xaaaaaaaa; //和1010 1010 1010 .。。。。 做与运算保留偶数位 相当于取出
return (ou>>1)^(ji<<1);
}
}
二进制表示浮点实数
public class Main {
public static void main(String[] args) {
double num = 0.625;
StringBuilder sb = new StringBuilder("0.");
while(num>0){
// 乘2:挪整
double r = num * 2;
// 判断整数部分
if (r>=1) {
sb.append("1");
// 消除整数部分
num = r - 1;
}else {
sb.append("0");
num = r;
}
if (sb.length()>34) { // 这里的34包括“0.”长度
System.out.println("ERROR");
return ;
}
}
System.out.println(sb.toString()); // 结果为0.101
}
}
出现一次和出现k次
public class find1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr={5,5,5,2,2,2,4,6,6,6};
int len = arr.length;
int [][] kRadix = new int[len+1][3];
int k=0;
//将2进制数转换成3进制数,存在2维数组中
for(int i=0;i<len;i++)
{
for(int j=0;j<3;j++)
{
kRadix[i][j]=arr[i]%3;
arr[i]/=3;
}
}
//输出高低位反着的3进制数
for(int i=0;i<len;i++)
{
for(int j=0;j<3;j++)
{
System.out.print(kRadix[i][j]);
}
System.out.println();
}
//进行不进位的加法
for(int j=0;j<3;j++)
{
for(int i=0;i<len;i++)
{
kRadix[len][j]+=kRadix[i][j];
kRadix[len][j]%=3;
}
}
//将个数为1的数存放在最后一行二维数组中
for(int j=0;j<3;j++)
{
System.out.print(kRadix[len][j]);
k+=kRadix[len][j]*(int)(Math.pow(3,j));//将3进制数转换为10进制数
}
System.out.println();
System.out.println("个数为一的数为:");
System.out.print(k);
}
}