在解决该题之前,我们先来了解一下十进制转换成二进制的方法
将十进制转换成二进制的方法
方法一:利用Interger.toBinaryString()的方法。
方法二:除基倒取余法
输入一个十进制数n,每次用n除以2,把余数记下来,再用商去除以2...依次循环,直到商为0结束,把余数倒着依次排列,就构成了转换后的二进制数
public class DecimalToBinary {
public static int decimalToBinary(int n){
//存余数
int r = 0;
//记录所求的二进制数
int bin = 0;
//记录位数
int t = 0;
while (n != 0) {
r = n % 2;
n = n / 2;
bin += (int) (r * Math.pow(10, t));
t++;
}
return bin;
}
public static void main(String[] args) {
int n1 = -9;
int n2 = 10;
int n3 = 1023;
int n4 = 1024;
int n5 = -1023;
int n6 = -1024;
System.out.println("十进制数"+n1+"所对应的二进制数为:"+decimalToBinary(n1));
System.out.println("十进制数"+n2+"所对应的二进制数为:"+decimalToBinary(n2));
System.out.println("十进制数"+n3+"所对应的二进制数为:"+decimalToBinary(n3));
System.out.println("十进制数"+n4+"所对应的二进制数为:"+decimalToBinary(n4));
System.out.println("十进制数"+n5+"所对应的二进制数为:"+decimalToBinary(n5));
System.out.println("十进制数"+n6+"所对应的二进制数为:"+decimalToBinary(n6));
}
}
结果:
十进制数-9所对应的二进制数为:-1001
十进制数10所对应的二进制数为:1010
十进制数1023所对应的二进制数为:1111111111
十进制数1024所对应的二进制数为:2147483647
十进制数-1023所对应的二进制数为:-1111111111
十进制数-1024所对应的二进制数为:-2147483648
从结果可以看出,该程序不能表示负数,且-1023到1023之间的十进制数可以用二进制表示,但是超过了1024就不行了。
为什么超过1024就不能表示了呢?因为这个程序我们表示二进制数的时候,我们用的依旧是十进制的形式,大家知道int的取值范围是-2147483648~2147483647.根据我们这个程序,1024所对应的二进制数为10000000000(注意:这个使用的十进制的形式),它超过了int的取值范围。所以它就会转换为一个其他的数字。但是为什么会是这个数字呢?
方法三:在方法二的基础上使用字符串对结果集进行存储
public class DecimalToBinary {
public static String decimalToBinary(int n){
String str = "";
while (n != 0) {
str = n % 2 + str;
n = n / 2;
}
return str;
}
public static void main(String[] args) {
int n1 = -9;
int n2 = 10;
int n3 = 1023;
int n4 = 1024;
int n5 = -1023;
int n6 = -1024;
int n7 = 1025;
System.out.println("十进制数"+n1+"所对应的二进制数为:"+decimalToBinary(n1));
System.out.println("十进制数"+n2+"所对应的二进制数为:"+decimalToBinary(n2));
System.out.println("十进制数"+n3+"所对应的二进制数为:"+decimalToBinary(n3));
System.out.println("十进制数"+n4+"所对应的二进制数为:"+decimalToBinary(n4));
System.out.println("十进制数"+n5+"所对应的二进制数为:"+decimalToBinary(n5));
System.out.println("十进制数"+n6+"所对应的二进制数为:"+decimalToBinary(n6));
System.out.println("十进制数"+n7+"所对应的二进制数为:"+decimalToBinary(n7));
}
}
结果:
十进制数-9所对应的二进制数为:-100-1
十进制数10所对应的二进制数为:1010
十进制数1023所对应的二进制数为:1111111111
十进制数1024所对应的二进制数为:10000000000
十进制数-1023所对应的二进制数为:-1-1-1-1-1-1-1-1-1-1
十进制数-1024所对应的二进制数为:-10000000000
十进制数1025所对应的二进制数为:10000000001
不足:这种方法只能处理正数
方法三改进:
public static String decimalToBinary(int n){
String result = "";
boolean minus = false;
//如果该数字为负数,那么进行该负数+1之后的绝对值的二进制码的对应位取反,然后将它保存在result结果中
if(n < 0){
minus = true;
n = Math.abs(n + 1);
}
while(true){
int remainder = (!minus && n % 2 == 0) || (minus && n % 2 == 1) ? 0 : 1;
//将余数保存在结果中
result = remainder + result;
n /= 2;
if(n == 0){
break;
}
}
//判断是否为负数,如果是负数,那么前面所有位补1
if(minus){
n = result.length();
for(int i = 1; i <= 32 - n; i++){
result = 1 + result;
}
}
return result;
}
public static void main(String[] args) {
int n1 = -1;
int n2 = 10;
int n3 = 1023;
int n4 = 1024;
int n5 = -1023;
int n6 = -1024;
int n7 = 1025;
System.out.println("十进制数"+n1+"所对应的二进制数为:"+decimalToBinary(n1));
System.out.println("十进制数"+n2+"所对应的二进制数为:"+decimalToBinary(n2));
System.out.println("十进制数"+n3+"所对应的二进制数为:"+decimalToBinary(n3));
System.out.println("十进制数"+n4+"所对应的二进制数为:"+decimalToBinary(n4));
System.out.println("十进制数"+n5+"所对应的二进制数为:"+decimalToBinary(n5));
System.out.println("十进制数"+n6+"所对应的二进制数为:"+decimalToBinary(n6));
System.out.println("十进制数"+n7+"所对应的二进制数为:"+decimalToBinary(n7));
}
结果:
十进制数-1所对应的二进制数为:11111111111111111111111111111111
十进制数10所对应的二进制数为:1010
十进制数1023所对应的二进制数为:1111111111
十进制数1024所对应的二进制数为:10000000000
十进制数-1023所对应的二进制数为:11111111111111111111110000000001
十进制数-1024所对应的二进制数为:11111111111111111111110000000000
十进制数1025所对应的二进制数为:10000000001
方法四:利用“移位”
public static String decimalToBinary(int n){
String str = "";
for(int i = 31; i >= 0; i--){
int s = n >>> i & 1;
str = str + s;
}
return str;
}
public static void main(String[] args) {
int n1 = -1;
int n2 = 10;
int n3 = 1023;
int n4 = 1024;
int n5 = -1023;
int n6 = -1024;
int n7 = 1025;
System.out.println("十进制数"+n1+"所对应的二进制数为:"+decimalToBinary(n1));
System.out.println("十进制数"+n2+"所对应的二进制数为:"+decimalToBinary(n2));
System.out.println("十进制数"+n3+"所对应的二进制数为:"+decimalToBinary(n3));
System.out.println("十进制数"+n4+"所对应的二进制数为:"+decimalToBinary(n4));
System.out.println("十进制数"+n5+"所对应的二进制数为:"+decimalToBinary(n5));
System.out.println("十进制数"+n6+"所对应的二进制数为:"+decimalToBinary(n6));
System.out.println("十进制数"+n7+"所对应的二进制数为:"+decimalToBinary(n7));
}
结果:
十进制数-1所对应的二进制数为:11111111111111111111111111111111
十进制数10所对应的二进制数为:00000000000000000000000000001010
十进制数1023所对应的二进制数为:00000000000000000000001111111111
十进制数1024所对应的二进制数为:00000000000000000000010000000000
十进制数-1023所对应的二进制数为:11111111111111111111110000000001
十进制数-1024所对应的二进制数为:11111111111111111111110000000000
十进制数1025所对应的二进制数为:00000000000000000000010000000001
说明:由于计算机中存储的都是数的补码,正数的原码、反码、补码都是相同的;而负数的原码、反码、补码是不一样的,补码=原码取反+1(符号位不变)。所以,负数是按照它的补码输出的。
>>>为逻辑移位符,向右移n位,高位补0
>> 算数移位符,也是向右移n位,不同的是:正数高位补0,负数高位补1
<< 移位符,向左移n位,低位补0
二进制中1的个数
题目描述:输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
分析:先将十进制的数转换成二进制数,再进行判断
解法一:将字符串转成字符数组的形式,遍历进行判断
public static int NumberOf1(int n) {
String result = Integer.toBinaryString(n);
System.out.println("n的二进制数:"+result);
//将字符串转换成字符数组,进行判断
char[] res = result.toCharArray();
int count = 0;
System.out.println("二进制位数:"+res.length);
for(int i = 0;i < res.length; i++){
if (res[i] == '1') {
count ++;
}
}
return count;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入一个数字n:");
int n = scanner.nextInt();
System.out.println(n+"的二进制数中表示1的个数为:"+NumberOf1(n));
}
测试结果:
请输入一个数字n:4
n的二进制数:100
二进制位数:3
4的二进制数中表示1的个数为:1
请输入一个数字n:-3
n的二进制数:11111111111111111111111111111101
二进制位数:32
-3的二进制数中表示1的个数为:31
建议:在上述方法中,我们是将二进制数直接用字符串输出;其实也可以利用Interger.parseInt()转化成int。但是不建议用这种方式,我试了一下,当输入数字为-3时,它的二进制数应该为11111111111111111111111111111101 ,但是此时出现了java.lang.NumberFormatException错误。这是为什么呢?
因为超过了int类型表示的范围.
解法二:Integer.toBinaryString(n).replace("0","").length();
public static int NumberOf11(int n) {
return Integer.toBinaryString(n).replace("0", "").length();
}
解法三:利用&
public static int NumberOf1(int n) {
int count = 0;
while (n != 0) {
count++;
n = n & (n-1);
}
return count;
}
如果没有看懂的话,我们来举个例子
假如 n = 5 count = 0
n 0101 5
n - 1 0100 4
n=n&(n-1) 0100 4 count = 1
n - 1 0011 3
n=n&(n-1) 0000 0 count = 2
进行了两次&运算,得到二进制5中的1的个数为2
延伸:& 按位与 & 既是位运算符又是逻辑运算符,&的两侧可以是int,也可以是boolean表达式,当&两侧是int时,要先把运算符两侧的数转化为二进制数再进行运算。若两个数都为1则为1,否则为0