java的数据类型如下:
整数类型
其中整形的规则是,高位是标志位 0是正,1是负,其余表示数字
- 1 byte = 8 bit; // 一个字节是8个二进制位
- 1 short = 16 bit;// 2字节 16位
- 1 int = 32 bit;// 4字节 32位
- 1 long = 64 bit;// 8字节 64位
以short为例
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|
符号位 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
+1 就是 0000 0001;
负数是将整数的每个二进制位取反,然后加1,1取反 1111 1110,加1 1111 1111,
-1 就是 1111 1111;
浮点类型
具体可以看这篇文章非常详细1
具体可以看这篇文章非常详细2
这里简单说明一下,浮点数使用的是科学计数法,会有精度问题;
- float占4个字节
- double占8个字节
8.25 转换为 8.25E0 就是 8.25 * 10^0;
120.5 转换为 1.205E2 就是 1.205 * 10^2;
计算机只认识二进制所以实际上
8.25 二进制 1000.01 = 1.00001 * 2^3;
120.5 二进制 1110110.1 = 1.1101101 * 2^6;
所有数字都可以表示成 1.xxx * 2^n, 所以将高位的1省略
所有浮点数都有3部分组成
+1.xxx * 2^n 将数字解析后如下
类型 | 符号位 | 指数位 | 尾数部分 |
---|---|---|---|
0是正,1是负 | n | xxx | |
float | 1位 | 8位 | 23位 |
double | 1位 | 11位 | 52位 |
精度问题是因为指数可表达的位数太大,而尾数部分的位数无法安全装下所有位数,所以将位数舍弃导致精度问题。
public static void main(String[] args){
// 先被转成二进制 然后转成
float f = 123456789012345667890000000000000000000F;
double d = 123456789012345678900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D;
int i = 1234567890;
long l = 1234567890123456789L;
System.out.println(f);// 结果 1.2345679E38
System.out.println(d);// 结果 1.2345678901234567E308
System.out.println(i);// 结果 1234567890
System.out.println(l);// 结果 1234567890123456789
}
整形本身没有精度问题,但是经过除法计算会有除不尽的情况,就会将小数点后面直接舍弃。
整形及浮点型的计算如果要求精度非常高可以使用 BigDecimal和BigInteger
//小数
BigDecimal bd = new BigDecimal(123.233445665544D);
//整数
BigInteger bi = new BigInteger("12345678901234567890");
for (int i = 0; i < 100; i++){
bi = bi.add(bi);
System.out.println(bi);
}
for (int i = 0; i < 100; i++){
bd = bd.add(bd);
System.out.println(bd);
}
类型转换
将取值范围小的类型的数据可以直接放到取值范围大的类型的数据中,不会出现放不下的情况,叫做自动类型转换;
byte bb = 1;
short ss = bb;
int ii = ss;
long ll = ii;
float ff = ll;
double dd = ff;
将取值范围大的数据赋值给取值范围小的数据,因为有可能放不下,出现精度损失,所以不能直接赋值;
可以采取强制类型转换的方法,就是在赋值的数据前加一个小括号,小括号里面写上数据类型;
ff = (float) dd;
ll = (long) ff;
ii = (int) ll;
ss = (short) ii;
bb = (byte) ss;
boolean类型
虽然定义了boolean这种数据类型,但是只对它提供了非常有限的支持。在Java虚拟机中没有任何供boolean值专用的字节码指令,Java语言表达式所操作的boolean值,在编译之后都使用Java虚拟机中的int数据类型来代替,而boolean数组将会被编码成Java虚拟机的byte数组,每个元素boolean元素占8位。
那虚拟机为什么要用int来代替boolean呢?为什么不用byte或short,这样不是更节省内存空间吗。经过查阅资料发现,使用int的原因是,对于当下32位的处理器(CPU)来说,一次处理数据是32位(这里不是指的是32/64位系统,而是指CPU硬件层面),32 位 CPU 使用 4 个字节是最为节省的,哪怕你是 1 个 bit 他也是占用 4 个字节。因为 CPU 寻址系统只能 32 位 32 位地寻址,具有高效存取的特点。
char类型
JAVA中的char类型
JAVA中,char占2字节,16位。可在存放汉字
char a=’a’; //任意单个字符,加单引号。
char a=’中’;//任意单个中文字,加单引号。
char a=111;//整数。0~65535。十进制、八进制、十六进制均可。输出字符编码表中对应的字符。
char类型是可以运算的因为char在ASCII等字符编码表中有对应的数值。
在JAVA中,对char类型字符运行时,直接当做ASCII表对应的整数来对待。
char m=’a’+’b’; ——Ã。 //char类型相加,提升为int类型,输出对应的字符。
int m=’a’+’b’; ——195。//195没有超出int范围,直接输出195。