题目
位运算解法
代码
class Solution {
public int numberOfSteps (int num) {
int cou=0;
while(num!=0){
num=num%2==0?num>>=1:num-1;
cou+=1;
}
return cou;
}
}
知识点
机器数&真值
机器数有符号位,0为正,1为负
真值则用“+”号表示正数,用“-”号表示负数
如: [-1] =[10000001](机器数)= [-000000001](真值)
机器数有三种表达方式:原码、反码、补码:
原码
原码表示法有一位符号位,(即最高位为符号位)正数该位为0,负数该位为1,其余位表示数值的大小,如:
[+1] =[00000001](原码);
[-1] =[10000001](原码);
此时8位二进制的取值范围就是[1111 1111,0111 1111]也就是[-127,127]
反码
反码是数值存储的一种,但不常用。
表示方法如下:
正数的反码是其本身
负数的反码是在其原码的基础上, 符号位不变,其余各位取反.
[+1] = [00000001](原码) =[00000001](反码) ;
[-1] = [10000001](原码) =[11111110](反码);
取值范围与原码一样
补码
在计算机系统中,数值一律用补码来表示和存储。
表示方法如下:
正数的补码是其本身
负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)
[+1] = [00000001](原码) =[00000001](反码) = [00000001](补码);
[-1] = [10000001](原码) =[11111110](反码)= [11111111](补码);
此时8位二进制的取值范围是[-128,127]
当把补码转换回原码时,可以先减一再取反,也可以先取反再加一,以四位二进制举例:
1001补 --(取反)–>0110–(加一)–>0111
1001补 --(减一)–>1000–(取反)–>0111
因为这里的取反相当于用1111减去原数,所以上面两步是等价的
采用补码的原因是补码能完美的将减法与加法统一,即将减法看作是和负数相加。
而且能多表示一位,因为在原码和反码中+0和-0的表达方式不同,但在补码中+0和-0都是[00000000],所以,[1000 0000]补就用来表示-128。* 但是注意因为实际上是使用以前的-0的补码来表示-128, 所以-128并没有原码和反码表示.*具体请看:
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/leng80919/article/details/52903588
注意补码运算过程中,如果产生进位,则自然丢失。
关于补码运算溢出,往往使用双进位的状态来判断:
V=D7c ⊕ D6c 其中D7c表示符号位是否进位,D6c 表示数值最高位是否进位,只有两个异或结果(两者不同才为1)为1时,即V=1,表示有溢出。
位运算
- m<<n m整体左移n位,右边空出位补0,左边位舍弃
m<<n即在数字没有溢出的前提下,
对于正数和负数,左移n位都相当于m乘以2的n次方. - m >>n m整体右移n位,左边空出位,负数补1,正数补0,右边位舍弃
- 无符号右移( >>> )同>>,但左边空出位都补0
- 与( & )每一位进行比较,两者都为1,结果为1,否则为0
常用于获得二进制数的某一位数字,比如想获得最后一位,就让数与1进行与运算。
return (n&1)==1;//true: 奇数;false: 偶数
- 或( | )每一位进行比较,两者有一个为1,结果为1
- 非( ~ ) 每一位进行比较,按位取反(符号位也要取反)
- 异或( ^ )每一位进行比较,相同为0,不同为1
1. a ^ b = b ^ a
2. a ^ b ^ c = a ^ (b ^ c) = (a ^ b) ^ c;
3. d = a ^ b ^ c 可以推出 a = d ^ b ^ c.
4. a ^ b ^ a = b.
详细可看:
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/javazejian/article/details/51181320
练习
题解
public class Solution {
// you need treat n as an unsigned value
public int reverseBits(int n) {
int res=0;
for(int i=0;(i<32);i++){
res|=(n&1)<<(31-i);
//取n最后一位并左移到相应位置
n>>>=1;
//每次取过后让n右移
}
return res;
}
}
进制转换
B :二进制数。 binary (0b开头)
Q (O):八进制数。 octonary (0开头)
D :十进制数。 decimal
H :十六进制数。 hexadecimal (0x开头)
其中十进制一般不加后缀
参考(https://jingyan.baidu.com/article/495ba84109665338b30ede98.html)
1. 二进制、八进制、十六进制 转 十进制
从左到右是按权展开,从右到左是取余法,以八进制和十进制的互转为例:
二进制和十六进制同理
2. 八进制或十六进制 转二进制
从左到右,每一位用取余法转成三位(四位)二进制,不够则在左边补零,然后拼在一起;
从右到左,将二进制从后到前,每三位(四位)转化成一位数,最前面不足则补零,然后拼在一起;
八进制是三位(2^3),十六进制是四位(2^4)
以八进制和二进制为例:
3.八进制转十六进制
借助二进制或十进制做媒介