本篇解释算法第一道题,原题在我的gitee中
https://gitee.com/xiao-baihao/algorithm-brushing/tree/master
首先在计算机中整型是32位的,也就是占4个字节 一个字节是8位
在java中整数都代表有符号整型
正数的最高位是0 负数是1
所有的算数运算符 + - * / % 都不是十进制的都是需要在背后转成位运算的二进制特别注意在运算的过程中看的是补码 结果的过程看的是原码,负数 = 取反(~) + 1;
为什么要取反加1
还有java中最大的数和最小的数
有符号数:用最高位最符号位,‘0’代表正数,‘1’代表负数,其余位用作数字位代表数值位。
无符号数:所有位都为数值位,无正负之分,亦无符号位
二进制转十进制:从最低位开始(右边低一位) 将每个位置上的数提出来,乘以2的(位数 -1)次方,然后把数加起来
一个字节有8位
0b0001011
1 * 2(1 - 1) + 1 * 2(2 - 1) + 0 * 2(3 - 1) + 1 * 2(4 - 1) = 11
八进制转十进制:从低位开始 将每个位置上的数提出来,乘以8的(位置 -1)次方,然后把数加起来
00000234
4 * 8(1 - 1) + 3 * 8(2 - 1) + 2 * 8(3 - 1) = 28 + 128 = 156
十六进制转十进制:从低位开始 将每个位置上的数提出来,乘以16的(位置 -1)次方,然后把数加起来
十六进制有1-9 A-F (A-F代表 10—16)
0x代表的是16进制它是一个标识符
0x0000023A
10 * 16(1 - 1) + 3 * 16(2 -1) + 2 * 16(3 -1) = 570
3400100010有一个凑数的方法:想好2的几次方是多少,比如说2^1(10)是2, 2^2(100)是4, 2^3(1000)是8, 2^4(10000)是16, 2^5是32,2^6是64, 2^7是128, 2^8是256, 2^9是512, 2^10 1024这样凑数的方法就可以得出 2^5 + 2^1 = 100000 + 10 = 100010可以利用这个方法算一个大的数2012可以拆成2^3 + 2^2 + 2^10 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4= 4 + 8 + 1024 + 512 + 256 + 128 896 - 976 = 8010000000000100000000010000000010000000100000010000100010011111011100
先转成二进制在转八进制
131 = 2^7 + 2^1 + 1 = 10000011
(10)(000)(011) = 203
2进制转八进制: 从低位开始将二进制每三位为一组,转成对应的八进制数即可,从后往前
10000011
(10)(000)(011) = 203
十进制转成16进制
先转2进制在转16进制
131 = 2^7 + 2^1 + 1 = 10000011
2进制转16进制:从低位开始将二进制每四位为一组,转成对应的16进制即可,从后往前
10000011
(1000)(0011) = 83
8进制转2进制,可以先转10进制然后在转2进制,16进制也一样
java中有7个运算符(&、|、^、~、>>、<<、>>>)
分别是 按位与&、按位或|、按位异或^、按位取反~
按位与&: 两位全为1,结果为1,否则为0
按位或|: 两位有一个1, 结果1, 否则为0
按位异或^: 两位一个为0,一个为1,结果为1 否则为0
按位取反~: 取反0和1
- 二进制的高位是符号位:0表示正数,1表示负数
- 正数的原码 反码 补码都一样
- 负数的反码 = 它的原码符号位不变,其他位取反
- 负数的补码 = 它的反码 + 1, 负数的反码 = 负数的补码 -1
- 0的反码和补码都是0
- Java没有无符号数,java都是有符号数, 整数类型就代表有符号数
- 计算机运算的时候,都是以补码的方式来运算的
- 当我们看运算结果的时候,要看他的原码
>>、>>>、<<
1. 算术右移>>: 低位溢出,符号位不变,并用符号位补溢出的高位
2. 算数左移<<: 符号位不变,低位补零
3. >>> 逻辑右移也叫无符号右移,运算规则是:低位溢出,高位补0
没有 <<< 符号
案列:1. int a = 1 >> 2; 1 / 2 / 22. int b = 1 << 2; 1 * 2 * 2;
右移就是除以2,左移就是乘以2
例子: 2&3、~-2、~2、2|3、^3
一、 2&3 首先要把十进制的数转换成原码也就是32为的2进制,一个字节是8位,一共有4个字节,然后在转成补码
2的原码 = 0000000000000000000000000000000010
2的补码 = 0000000000000000000000000000000010
3的原码 = 0000000000000000000000000000000011
3的补码 = 0000000000000000000000000000000011
(0000000000000000000000000000000010) & (0000000000000000000000000000000011)
结果:0000000000000000000000000000000010 = 2二、~-2
-2的原码 = 1000000000000000000000000000000010
-2的反码 = 1111111111111111111111111111111101
-2的补码 = 1111111111111111111111111111111110
~-2 = 0000000000000000000000000000000001
结果:0000000000000000000000000000000001 = 1三、~2
2的原码:0000000000000000000000000000000010
2的补码:0000000000000000000000000000000010
~2补码:1111111111111111111111111111111101
拿到反码:1111111111111111111111111111111100
拿到原码:1000000000000000000000000000000011
结果:1000000000000000000000000000000011 = 3