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

来源:互联网 发布:如何联系淘宝投诉店家 编辑:程序博客网 时间:2024/05/10 14:40

数学问题:

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                                           0shot(短整型)        16      -32768 - 32767                                         0int(整型)           32   -2147483648-2147483647                                    0long(长整型)        64   -9233372036854477808-9233372036854477807                  0        float(浮点型)       32  -3.40292347E+38-3.40292346E+38                            0.0fdouble(双精度)    64  -1.79769313486231570E+308-1.79769313486231570E+308        0.0dchar(字符型)        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          *           */                }  





原创粉丝点击