java数据类型和各类型之间的转换,以及进制的转换
java的数据类型包括 基本数据类型 和 引用数据类型 。
java是一个强类型的编程语言。
所有的变量在第一次出现的时候 必须有数据类型。
面试题:
java中的数据类型分为几种?
2种/无数种
2种指:基本数据类型、引用数据类型
无数种:引用数据类型是我们自定义的类,没有数量限制
基本数据类型
又称为简单数据类型[程序里面自带的数据类型]
基本数据类型分为4类共8种。
java的基本数据类型包括:布尔类型、字符类型、整数类型、浮点类型。
布尔类型
boolean -> 只能使用true/false进行赋值,不能使用数字赋值【c、c++、c#可以】。
- :当我们开发的时, 想要描述一种对立状态的时候。
字符类型
char
- 16位
- 底层基于Unicode编码实现的
- 不区分中英文
- 统一的都是2个字节 = 16位 (一个字节等于8位)
- char类型与整型和浮点型进行加减乘除操作时会转换为浮点型和整形进行加减乘除操作
*:当我们要描述一个字/字母的时候 -》 性别
char x1 = 'a';//指定字面值的复制方式
char x2 = '中';//指定字面值的的赋值方式
char x3 = 77;//通过ascii编码进行赋值
char x4 = '\u4e2d';//通过Unicode编码进行赋值
char x5 = '\t';//转义字符
转义字符:
\t | \r | \n | \b |
---|---|---|---|
制表符 | 返回行首 | 换行 | 退格键 |
\r:返回行首的制表符在使用后,光标会移动到该行之首,再次录入信息时,会逐个字符的替代已经输入的字符。
赋值:
//当我们拿着一个数字给char类型赋值的时候
//这个数字可能是int类型也可能是ascii编码
//如果这个数字在char类型的取值范围里面的话 数字 -》 ascii编码
char x = 97;//ascii编码
//如果这个数字不再char类型的取值范围里面的话 数字 -》 int
char y = -97;//int(当然,这种情况系统会报错) char取值范围:0-65535
获取一个字符的unicode方法:
cmd -> native2ascii(实际上就是一个字符的16进制,前面增加\u标志)
获得一个字符Ascii的方法:
cmd -> calc(使用电脑自带的计算器,将字符的Unicode转换为10进制)
整数类型
占用的位数:
符号位1 + 数值位【n-1】
取值范围:-2^(n-1)到 2^(n-1)-1
n : 指位数
(n-1) : 符号为占用一个位
-1 :0占用一个位
整数类型的位和字节数
1 | byte | short | int | long |
---|---|---|---|---|
位 | 8 | 16 | 32 | 64 |
字节 | 1 | 2 | 4 | 8 |
范围:
- -2(n-1)次方~2(n-1)次方-1
- byte:-128~127
- short:-32768~32767
- int:-2147483648~2147483647
- char:0到2^(16)-1【0-65535】
当超出范围时:
- 写成二进制,从后开始取相应的位数,然后重新变为十进制。
public class Exec5{
public static void main(String[] args){
short s = 200;
byte b=(byte)s;
System.out.println(b);
}
}
/**
200=128+64+8=11001000
short:0000000011001000
byte:11001000=-1-x
=11111111-x
=11111111-1-2-4-16-32=-1-1-2-4-16-32=-16-39=-56
*/
*:整数类型默认是int类型
*:long类型结尾尽量加上L
*:当数值超出int类型最大边界的时候 注意使用long类型
多进制赋值
int num1 = 24;//通过十进制进行赋值 *****
int num2 = 024;//通过八进制进行赋值
int num4 = 0b1011;//通过二进制进行赋值 since jdk7.0版本才能使用
System.out.println(num1);//24
System.out.println(num2);//024 = 2 * 8(1) + 4 * 8(0) = 16 + 4 = 20
System.out.println(num3);//0x24 = 2 * 16(1) + 4 * 16(0) = 32 + 4 = 36
System.out.println(num4);//11
// 81 + 8 * 8(1) + 1 * 8(0) + 8 * 16(1) + 1 * 16(0)
System.out.println(81 + 081 + 0x81);//错误,8进制不能有8
//二进制:0 1
//八进制:0-7
//十六进制:0-9 a-f
十进制和二进制之间的转换
正数:
记住这个顺序:
1 2 4 8 16 32 64 128 256 512 1024....2(n)
byte x = 55;
55 = 32 + 16 + 4 + 2 + 1 = 00110111
byte x = 100;
100 = 64 + 32 + 4 = 01100100
将有的数写为1,没有的数写为0,不足位的用0在最前面补齐。
负数:
用补码表示的
任何一个整数类型,如果底层二进制位上全是1的话,表示该类型十进制的-1
byte:11111111 -> -1
short:1111111111111111 -> -1
1 2 4 8 16 32 64 128 256 512 1024....2(n)
byte x = -59;
-59 = -1 - 58 = -1 - 32 - 16 - 8 - 2
= 11111111 - 32 -16 - 8 - 2
= 11000101
*将有的数字对应的位改为0
byte x = 88;
88 = 64 + 16 + 8 = 01011000
byte y = -88;
-88 = -1 - 87 = -1 - 64 - 16 - 4 - 2 - 1 = 10101000
1 2 4 8 16 32 64 128 256 512 1024....2(n)
byte x = 49;
49 = 32 + 16 + 1 = 00110001
byte y = -49;
-49 = -1 - 32 - 16
= 11001111
思考题:
有10瓶药 里面有9瓶是无毒的 有1瓶毒药
小白鼠只要喝了毒药 就会在7天后死掉
但在7天内没有任何反应
现在只给4只小白鼠和7天时间
如何测试出来哪瓶药是毒药?
第一瓶药:0001
第二瓶药:0010
第三瓶药:0011
第四瓶药:0100
第五瓶药:0101
第六瓶药:0110
第七瓶药:0111
第八瓶药:1000
第九瓶药:1001
第十瓶药:1010
A:倒数第一个位上全是1 -》 1 3 5 7 9
B:倒数第二个位上全是1 -》 2 3 6 7 10
C:倒数第三个位上全是1 -》 4 5 6 7
D:倒数第四位上全是1 -》 8 9 10
浮点类型:
1 | float | double |
---|---|---|
位 | 32 | 64 |
字节 | 4 | 8 |
标志 | F/f | D/d |
*:经常在涉及到钱时使用 -》 工资 单价
二进制:
符号位 + 幂指位 + 数值位
- float:符号位1 + 幂指位8 + 数值位23
- double:符号位1 + 幂指位11 + 数值位52
浮点类型和二进制之间的转换
正数:
float x = 45.5F;
1:将两个部分全部转换成二进制
a:45 = 32 + 8 + 4 + 1 = 101101
b:0.5 = 1
*:不断*2取整
0.5 * 2 = 1.0
组合:
a + b = 101101.1
2:将上面的结果转换成二进制的科学计数法
101101.1
1.011011 * 2(5)
3:对号入座:
符号位1 + 幂值位8 + 数值位23(float的幂指位为8位,double的幂指位为11位)
0 10000100 01101100000000000000000
幂指位的计算:
127+2的平方次数
127 + 5 = 132 = 128 + 4 = 10000100
01000010001101100000000000000000
float x = 76.75F;
1:将上面的两个部分全部转换成二进制
76 = 64 + 8 + 4 = 1001100
0.75 = 11
0.75 * 2 = 1.5
0.5 * 2 = 1.0
1001100.11
2:将上面的结果转换成二进制的科学计数法
1001100.11
1.00110011 * 2(6)
3:符号位 + 幂值位8 + 数值位23
0 10000101 00110011000000000000000
127 + 6 = 133 = 128 + 4 + 1 = 10000101
01000010100110011000000000000000
float x = 21.25F;
1:将上面的两个部分全部转换成二进制
21 = 16 + 4 + 1 = 10101
0.25 = 01
0.25 * 2 = 0.5
0.5 * 2 = 1.0
10101.01
2:将上面的结果转换成二进制的科学计数法
10101.01
1.010101 * 2(4)
3:符号位1 + 幂值位8 + 数值位23
0 10000011 01010100000000000000000
127 + 4 = 128 + 2 + 1 = 10000011
01000001101010100000000000000000
float y = 17.1F;
1:将上面的两个部分全部转换成二进制
17 = 16 + 1 = 10001
0.1 = 000110011[0011](形成了循环数)
0.1 * 2 = 0.2
0.2 * 2 = 0.4
0.4 * 2 = 0.8
0.8 * 2 = 1.6
0.6 * 2 = 1.2
0.2 * 2 = 0.4
0.4 * 2 = 0.8
0.8 * 2 = 1.6
10001.000110011[0011]
2:将上面的结果转换成二进制的科学计数法
10001.000110011[0011]
1.0001000110011[0011] * 2(4)
3:符号位 + 幂值位 + 数值位23(循环的情况只取到相应的位数忽略剩余的位数)
0 10000011 00010001100110011001100
127 + 4 = 128 + 2 + 1 = 10000011
01000001100010001100110011001100
负数:
除了符号位为1外,没有区别
注意:
正是因为浮点数在处理时可能存在除不开导致出现无穷数然后进行忽略的现象,所以浮点数是不可靠的。
比如:0.1在显示时就有问题,等于0.100000001
//System.out.println(2.0 - 1.1);
面试题:(BigDecimal和0.1的精度问题)
1: 2.0-1.1结果为多少?
反正不是0.9
2: 为什么会出现这样的结果?
在java中任何一个整数类型都可以用二进制精确的表示出来
但是不代表任何一个小数也可以在有限的位数里面精确的表示出来
1.1在底层存储的时候 数值位出现了截取 导致数值不正确.
3:怎么解决?
(1)方法一:数值扩大100倍 单位缩小100倍
(2)方法二:使用BigDecimal类
BigDecimal b1 = new BigDecimal("2.0");
BigDecimal b2 = new BigDecimal("1.1");
BigDecimal b3 = b1.subtract(b2);//相减
BigDecimal b3 = b1.add(b2);//相加
*使用时需要引入:import java.math.*;
可能出现无限死循环的浮点类型值:0.1、0.2、0.4
基本数据类型之间的转换:
- 小的数据类型可以直接赋值给大的数据类型
- 大的数据类型需要强转成小的数据类型
- char转换为10进制的表现形式参与运算
引用数据类型
自定义的数据类型,即程序员定义的类。
使用时:
- 先开发测试类(含有main方法)
- 再次开发实体类
- 在main方法中创建对象
- 给对象赋值
- 调用对象的方法