java算法之数学问题(位操作)

本文探讨了一个利用位操作解决的数学问题,通过分析2017与2016的位操作,揭示了位与操作的规律。在进行7次与操作后,结果变为0。同时,文章回顾了Java中int类型的位操作相关知识点,包括位运算符的使用、整型转二进制的方法以及移位操作中考虑符号位的重要性。

数学问题:

public static int flag(int n) {
		int count=0;
		while(n>0){
			System.out.println(Integer.toBinaryString(n));
			n=n&(n-1);
			count++;
		}
		return count;
	}

问:flag(2017)结果,count为多少?

思路:这个问题是对位进行操作,n&(n-1)代表什么?当我们没有思路时,我们就要按照程序在跑起来,首先拿出一张纸,算出2017的二进制和2016的二进制

2017:11111100001

2016:11111100000

进行与操作得到:2016:11111100000,接下来呢?

2016:11111100000

2015:11111011111

进行与操作,得到:11111000000

这时候我们就可以发现规律了,接下来每一次与操作,都会减少最后的的一个1

因此总共,需要进行7次与操作,结果为0,结果count等于7。


总结:其实我对位操作心里一直是犯怵的,原因可能就是我对位操作很陌生把其实前一段时间刚刚对位操作进行了复习,不过看到这个题的时候,脑袋里比之前熟悉了一点,但还是有点陌生的。

接下来是我做这个题的时候,脑袋回顾知识点的时候,心里对位操作的疑问,现在刚好进行一个解答。

1. int整形的二进制多少位?表示的数字范围是多少?多少的时候会无法表示?

int整形在java中是占4个字节的,也就是32位,2的32次方表示的值为4294967296,说明int默认是有符号的。

数据类型            大小       范围                                             默认值 

byte(字节) 	    8         -128 - 127                                           0
shot(短整型)        16      -32768 - 32767                                         0
int(整型)           32   -2147483648-2147483647                                    0
long(长整型)        64   -9233372036854477808-9233372036854477807                  0        
float(浮点型)       32  -3.40292347E+38-3.40292346E+38                            0.0f
double(双精度)	    64  -1.79769313486231570E+308-1.79769313486231570E+308        0.0d
char(字符型)        16         ‘ \u0000 - u\ffff ’                             ‘\u0000 ’
boolean(布尔型)     1         true/false                                         false
int a=2147483647 +1;  //当直接输入2147483648,编译器会报错说是超过长度。
 System.out.println(a);   //  -2147483648

也就是说,当int的数值超过2的31次方时,就不能够用int表示。。

2. 整形怎么转换成二进制

可以用系统函数调用Integer.toBinaryString(int n)

也可以自己写函数:

public static String getBinary(int n) {
		StringBuffer s=new StringBuffer();
		while(n!=0) {
		s=s.append(n%2);
		n=n/2;
		}
		s=s.reverse();
		return s.toString();
	}

3. 与,或,非,异或的操作符号:

与:& 

或:|

非:~

异或:^

左移:>>(不考虑符号位),>>>(考虑符号位)

右移:<<,<<<(同上)

考不考虑符号位有什么区别:

计算机中存储二进制,全部以补码的形式存储,

考虑符号位,就是当是负数移位时,考虑的话高位补1,不考虑高位补0

当是正数移位时,没有差别


 public static void main(String[] args) {  
        /* 
         * 5 
         *  
         * 00000000 00000000 00000000 00000101 
         */  
        int a = 5;  
        int a1 = a>>1;  
        int a2 = a>>>1;  
        System.out.println(a1+"--"+a2); //2--2  
          
        /* 
         * -5 
         *  
         * 10000000 00000000 00000000 00000101  --原码 
         * 11111111 11111111 11111111 11111010  --反码 
         * 11111111 11111111 11111111 11111011  --补码 
         *  
         * 11111111 11111111 11111111 11111101  --(-3) 
         * 01111111 11111111 11111111 11111101  --(2147483645) 
         */  
        int b = -5;  
        int b1 = b>>1;  
        int b2 = b>>>1;  
        System.out.println(b1+"--"+b2); //-3--2147483645  
          
        /* 
         * 总结: 
         * 1.>> 需考虑符号位 
         * 2.>>> 不考虑符号位,缺少的位数补0 
         *  
         */  
          
    }  





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值