进制数、数据存储单位、char、封装类、原码反码补码、移位运算符、位运算符
进制数
十进制
逢十进一
二进制
取值是 0 或 1 ,
进制规则——逢二进一
二进制转十进制
权相相加法
Java表示:int a = 0b1010;
其中0b 表示二进制的前缀
十进制转二进制
除2区取余,逆序排序,最后的0不要
即 29 的二进制数为 11101
摩斯电码
八进制
十进制的 10 = 八进制的 12
在Java中要求 0 开头的是八进制
八进制 -> 十进制——类似于二进制,不过是8的n次方
十进制 -> 八进制——类似于二进制,不过是除以8
十六进制
0~9 正常表示 10~15 a b c d e f
数据存储单位
二进制中每位0或者1称为bit(位)
- 1byte = 8bit
- 1kb = 1024byte
- 1mb = 1024 kb
- 1gb = 1024 mb
- …
U 盘中标准进制是1000 不是 1024 所以我们买到的U盘大小与实际大小不符
byte 存储单位
1byte = 8bit
由于首位表示正负
所以表示范围为 -2^7 ~ 2^7-1
减一是因为 10000000 可以表示为 -2^7 而 正数最大值不能使用首位bit
0b00000000->0
0~255共256个
short 存储单位
1 short = 2 byte = 16bit
故short 的表示范围为 -215~ 215-1
boolean 存储单位
需要由 jvm 决定存储的大小,最小为1byte
char
可存储一些字符,无论 char 存储 什么内容都会对应 Unicode 中一个字符编号2,因为在内存或者硬盘中都会变成二进制
语法
char 变量名=‘value’;
Ascii 码 与 Unicode
Ascii 码是最初国外研究为了支持英文的字符,
后来各国家都需要能支持自己的字符,
于是在 Ascii 的基础上添加了自己国家的字符,比如中国的 GBK(表示国标)有许多的版本
但是每个国家倘若都有自己的一套太乱并且不通用
所以推出了 Unicode 万国码,统一全国的字符,
而Unicode虽然统一了字符集,
但是编码时所有字符的所占空间一样,导致浪费空间,
所以产生了UTF-8,专门针对 Unicode 提供的字符集进行可变长度的编码
可以分配 1、2、3(汉字字节长度)、4字节
常说的乱码就是指编码与解码使用的不是同一种方式
char 的ascii与整型的关系
char c ='a';
int num = c;
---------------
int num1 = 97;
char c1 = (char) num1;
八大基本类型对应的封装类
为了提供对应的方法
- byte——Byte
- short——Short
- long——Long
- float——Float
- double——Double
- boolean——Boolean
- int——Integer
- char——Character
使用方法
1、封装类型 变量名 = new 类型(值);
2、类型 对象名 = 类型.valueof(值);
3、类型 对象名 = 值;
注意封装类的赋值:
- Byte——直接赋值
- Short——直接赋值
- Integer——直接赋值
- Long——最后必须加 L / l
- Double——最后必须加 D / f
- Float——最后必须加 F / f
一定要注意跟基本数据类型分开
封装类中的常用方法
将字符串中类型转换为基本数据类型
语法:基本数据类型 变量名 = 封装类型 . parse封装类型(字符串值);
例:String str = “100”;
byte by = Byte.parseByte(“str”);
short sh = Short.parseShort(“str”);
…
除了 Character 其余类型都可以这样转换
封装类型的最大值与最小值
例:Integer.MAX_VALUE
十进制转为2进制、8进制、16进制
- 二进制——Integer.toBinaryString(十进制值)
- 八进制——Integer.toOctalString(十进制值)
- 十六进制——toHexString(十进制值)
注意返回的值都是String
原码、补码、反码
原码正数可以正常加,但是无法解决负数参与的运算
反码解决了原码的负数参与的运算,
其中反码若进位超过最高位数,则在得到的得数反码上加1,
但是又有了新问题:无法解决 -a+a的问题,得到的不是0,而是 -0
补码在反码的基础上解决了 -a+a 的问题
负数的补码是其反码+1
当补码进位发生与反码类似的情况时,直接舍弃进位的值
但是补码要结果 -1->得到反码 -> 然后才能得到原码
正数与0的原码、反码、补码都是其本身
原码
下面以 int 为例
正数和正数的相加
正数和负数的相加
右图片可以看出,如果有负数参加运算,结果明显不是想要的
负数与负数的相加
反码
负数运算时需要使用补码,而想要得到补码就要先得到其反码,
反码就是首位表示正负值得不变,其余 0变1 1变0,
从而得到反码
反码的正数与负数相加
负数和负数相加
-a + a
发现这里本应该是0才对,却得到了 -0的原码
补码
补码就是反码+1
-a + a
负数和负数相加
移位运算符
- << ——左位移运算符
>>
——右位移运算符>>>
——无符号右位移
左位移
整体左移,右侧补0,不考虑符号位
特点:被位移的数字 *2位移数
正数的左位移
int num = 2;
num = num << 2;
负数的左位移
int num = -2;
num = num << 2;
特殊情况示例
移位后超出范围
给出int变量值2147483647(int的最大值),对应的二进制数据为:
左位移1位后变为
右位移
整体右移,左侧补充符号位,右侧被移出的舍弃
特点:被位移的数字 /2位移数
正数的右位移
int num = 4;
num = num >> 1;
特殊情况说明
正数右位移最小值为0
负数右位移最小值为-1(因为需要是补码,换成反码需要减一)
无符号右移
无符号右移是无论数字为正数和负数,右移时左侧都补0.
所以正数右移的结果就是除以2的n次方,最小为0。负数右移结果会变大,随着移动的位数逐渐变小,最后为 0.
七. 位运算符
Java中常见的按位运算符有按位与&、按位或|、按位非~、按位异或^
1. 按位与
按位与: &
规则:全1为1,否则为0.
代码示例:
int a = 13;
int b = 5;
System.out.println(a&b); //5
2. 按位或
按位或: |
规则:有1为1,全0为0.
代码示例:
int a = 13;
int b = 5;
System.out.println(a|b); //13
3. 按位异或
按位异或:^
规则:不同为1,相同为0
代码示例:
int a = 13;
int b = 5;
System.out.println(a^b); //8
4. 按位非
按位非: ~ (一元运算法)
规则:按位取反。用于对一个数字类型进行按位非。
代码示例:
int a = 13;
System.out.println(~a); //-14
5. 位运算重要吗
位运算在各大算法底层经常出现。
6. 运算符优先级
*优先级* | *运算符* | *类* | *结合性* |
---|---|---|---|
1 | () | 括号运算符 | 由左至右 |
2 | !、+(正号)、-(负号) | 一元运算符 | 由左至右 |
2 | ~ | 位逻辑运算符 | 由右至左 |
2 | ++、– | 递增与递减运算符 | 由右至左 |
3 | *、/、% | 算术运算符 | 由左至右 |
4 | +、- | 算术运算符 | 由左至右 |
5 | <<、>> | 位左移、右移运算符 | 由左至右 |
6 | >、>=、<、<= | 关系运算符 | 由左至右 |
7 | ==、!= | 关系运算符 | 由左至右 |
8 | & | 位运算符、逻辑运算符 | 由左至右 |
9 | ^ | 位运算符、逻辑运算符 | 由左至右 |
10 | | | 位运算符、逻辑运算符 | 由左至右 |
11 | && | 逻辑运算符 | 由左至右 |
12 | || | 逻辑运算符 | 由左至右 |
13 | ? : | 条件运算符 | 由右至左 |
14 | =、+=、-=、*=、/=、%= | 赋值运算符 | 由右至左 |