谈谈Java基本数据类型
说到Java的基本数据类型,我们可能都能想到4类8种基本数据类型:
1、整型 byte、short、int、long分别用8、16、32、64bits来存储。
2、浮点型fl点型float、double分别用32/64bits来存储。
3、字符型char用16bits存储。
4、布尔型boolean可以用1bits来存储,其实布尔型没有明确的大写规定,jvm在编译期间会将boolean类型转换为int类型,用0表示true,用1表示false。
说说基本数据类型int的取值范围
也许进入工作岗位后,我们很多的人都还记得每种基本数据类型占多少位,但是很多的人都会忘了每种基本数据类型的取值范围(boolean除外)。在三年前的一次面试中面试官上来的第一个问题就是int的取值范围,当时我只答出了32位,尴尬的气氛导致连用科学计数的方式,都没说出int的最大取值范围与最小取值范围。直到面试结束在回去的地铁上才捋清思维想到了【-2^31,2^31 -1】。
为了让大家更清楚的记得,每种基本数据类型的取值范围,我在这里和大家一起,以4bits数为例进行一次最大、最小值的推演。
我们都知道计算机底层都是以二进制存储,以4位二进制数为例,其最大值为1111等于10进制的2^3+2^2+2^1+2^0=8+4+2+1=15。但很显然这样是不行的,因为我们的整数包含正数和负数,所以必须的用一位来作为标志,表示该整数是正数还是负数。如下图以最高位为0表示正数:
0
1
| 0 | 000 |
0 | 001 | |
0 | 010 | |
0 | 011 | |
0 | 100 | |
0 | 101 | |
0 | 110 | |
0 | 111 |
0
-1
| 1 | 000 |
1 | 001 | |
1 | 010 | |
1 | 011 | |
1 | 100 | |
1 | 101 | |
1 | 110 | |
1 | 111 |
我相信聪明的你一定会发现一个问题,就是0出现了两次一个正0一个负0,很显然这样是不妥的。因为我们都知道0既不是正数也不是负数,那怎么办呢?这个时候我们必须引入一个名词:“补码”,我们可以使用补码来表示负数,补码是啥呢,对二进制数的所有位取反然后加1得到的就是这个二进制数的补码。
于是我们只需在特殊处理负0为-8,其他负数除符号位外取补码即可,于是有:
补码
-1
-2
| 1 | 111 |
1 | 110 | |
1 | 101 | |
1 | 100 | |
1 | 011 | |
1 | 010 | |
1 | 001 | |
1 | 000 |
由此我们可以推算int的最大值为:0111...111即:2^(32-2) + 2^(32-3) + ... + 2^ + 2^0这里我们套用等比数列前n项和公式:Sn=a1(1-q^n)/(1-q)得到int的最大取值范围为:2^31-1。
同理我们可以得到int的最小取值范围为:-2^31。
基本数据类型的强制转化与自动转化
基本数据类型默认支持向上的自动转型,也就是说小的数据类型可以自动转化为大的数据类型,大的数据类型必须强制申明才能转换成小的数据类型。演示代码如下:
int a = 1;
byte b = 2;
int c = b; //自动向上转型
byte d = (byte)a; //必须强制转换
单精度浮点数float和双精度浮点数double
关于浮点数的使用
在使用和计算浮点数的时候:如果我们没有在浮点数后面加上F或者f,则浮点数都会默认被转化为double。
浮点数为什么不精确?
怎么来理解这句话呢,通俗一点说就是我们现实生活中习惯使用的10进制小数,在计算机底层无法用二进制的小数来精确的表达。
例如二进制小数1.11等于十进制的 2^0 + 2^-1 + 2^-2 = 1 + 1/2 + 1/4 = 1.75.
同理我们再来计算一个十进制小数0.3
0.1 = 1/2 = 0.5 大了
0.01 = 1/4 = 0.25 小了
0.011 = 1/4 + 1/8 = 0.25 + 0.125 = 0.375 又大了
0.0101 = 1/8 + 1/32 = 0.25 + 0.03125 = 0.28125 又小了但是靠进0.3了
0.01011 = 1/8 + 1/32 + 1/64 = 0.25 + 0.03125 + 0.015625 = 0.296875 又近了
差不得了哈哈约等于0.3了
由此可见浮点数是不精确的,如果我们要进行精确计算可以使用BigDecimal类。
“重走Java路-Java基本数据类型”的分享就到此结束了,预知后文请听下回分解“重走Java路-基本数据类型的包装类及引用数据类型”。