目录
无符号数和有符号数
无符号数
有符号数
Java数据类型分类
基本数据类型
整型
浮点型
标准浮点数
Java中数据类型转换问题
自动类型转换
强制类型转换
没有正负号的数据,寄存器的位数即为无符号数的表示范围。
分为符号部分和数值部分。
机器数保存符号、小数点位置以及数值。计算机中没有专门的硬件保存小数点,都是以约定的形式给出。
原码表示法:
整数:符号位+,+数值。符号位0为正,1为负。逗号将符号位和数值分隔开,数值其实是数的绝对值。
小数:符号位+.+小数部分,符号位0为正,1为负。小数点将符号位和小数部分分隔开。
上面的逗号和小数点,都不需要在计算机中存储,这里是方便人来阅读。
使用原码进行加法的时候,结果的符号可正可负,希望找到一个与负数等价的正数来替代这个负数,这样就可以使得减法变成加法,即补码表示法。
补码表示法:
整数:正数的补码与原码一致,负数的补码为它的原码,除符号位以外,各位取反,最后加1。
小数:正数的补码与原码一致,负数的补码为它的原码,除符号位以外,各位取反,最后加1。
反码表示法:
正数的反码就是原码,负数的反码,将原码除符号位外,所有位取反。
三种机器数的小结:
- 最高位为符号位,书写上用“,”(整数)或“.”(小数)将数值部分和符号位隔开
- 对于正数,原码=补码=反码
- 对于负数,符号位为1,其数值部分将原码除符号位以外每位取反——反码,再将反码+1——补码
在计算机底层,所有的数值都是以补码的形式存在的。
Java中数据类型主要分为两类,分别是:基本数据类型和引用数据类型。今天我们主要针对基本数据类型中的整数与浮点数进行赘述,因为这在数据存储的时候存在着一些问题,清楚认知其本质后才能使在后面代码的编写中更加顺畅。
在了解基本数据类型之前,首先我们需要简单了解以下计算机内存的基本结构:
计算机内训的最先存储单元是字节(byte),一个字节等于一个8位二进制数,即8bit。它的二进制数表示范围从00000000~11111111,换算成十进制是0~255,换算成十六进制是00~ff。
一个字节是1byte,1024byte字节是1K,1024K是1M,1024M是1G,1024G是1T。
基本数据类型是CPU可以直接进行运算的数据类型。在Java中定义了以下8种基本数据类型:
整数类型:byte,short,int,long
浮点数类型:float,double
字符类型:char
布尔类型:boolean
不同的数据类型占用的字节数不一样,Java基本数据类型占用的字节数:
整数类型:
┌───┐
byte │ │ 1个字节
└───┘
┌───┬───┐
short │ │ │ 2个字节
└───┴───┘
┌───┬───┬───┬───┐
int │ │ │ │ │ 4个字节
└───┴───┴───┴───┘
┌───┬───┬───┬───┬───┬───┬───┬───┐
long │ │ │ │ │ │ │ │ │ 8个字节
└───┴───┴───┴───┴───┴───┴───┴───┘
浮点数类型:
┌───┬───┬───┬───┐
float │ │ │ │ │ 4个字节
└───┴───┴───┴───┘
┌───┬───┬───┬───┬───┬───┬───┬───┐
double │ │ │ │ │ │ │ │ │ 8个字节
└───┴───┴───┴───┴───┴───┴───┴───┘
字符类型:
┌───┬───┐
char │ │ │ 2个字节
└───┴───┘
布尔类型:
┌───┐
boolean │ │ 1个字节 //通常JVM内部使用4字节int类型整数储存boolean值
└───┘
本文着重针对整型与浮点型进行研究。
对于整型类型,Java值定义了带符号的整数,因此,最高的数位表示符号位,0表示整数,1表示负数。
用byte举例,就是一个字节八位的数(即八个二进制的0或者1):
最大值: 0 111 1111 (十进制的127)
最小值: 1 111 1111 (十进制的-127)
其中:
0 000 0000 —— +0
1 000 0000 —— - 0
但事实上,0没有正负之分,因此规定,-0表示1 111 1111 - 1 即 -128,因此,符号位的存在也使得我们数据类型的取值范围比正常情况下多了一个数值。
下面将罗列不同整型能表示的最大范围:
- byte: -128 ~ 127 (2^-7 ~ 2^7 -1)
- short: -32768 ~ 323767 (2^-15 ~ 2^15 -1)
- int: -2147483648 ~ 2147283647 (2^-31 ~ 2^31 -1)
- long: -9223372036854775808 ~ 9223372036854775807 (2^-63 ~ 2^63 -1)
浮点类型的数值就是小数,因为小数用科学计数法表示的时候,小数点是可以“浮动”的,因此将其称为浮点数。(如1.2345 × 10^4 = 123.45 × 10^2)
类型 | 数符 | 阶码 | 尾数数值 | 总位数 |
---|---|---|---|---|
短浮点数 | 1 | 8 | 23 | 32 |
长浮点数 | 1 | 11 | 52 | 64 |
短浮点数又称为单精度浮点数(Float),长浮点数又称为双精度浮点数(Double)。
阶码是机器数里浮点数中的称谓,阶码指的就是浮点数中的指数,它表示了浮点数中这个小数点的具体位置。
对于单精度浮点数,我们可将尾数为的最大值近似看为1,那么Float的取值范围就会由阶码部分决定,阶码中有一位是阶码的数值位,那么Float可表示的最大值约等于2^127(符号位为0),而最小值为-2^127(符号位为1),那么这个取值范围是远比Long要大的(2^-63 ~ 2^63 -1)。
在Java中分为自动数据类型与强制数据类型转换。
格式: 大范围变量类型 变量名 = 小范围变量值
在将小范围变量的值存入大范围数据类型时,会发生自动类型转换,这种转换是安全的。
举个例子,你有两百万,你想将钱存入最多能存放两千万的银行中,这自然是可行的,银行无需询问你,这些钱也会原封不动,分文不少的存入。
我们之所以要讨论八字节Long与四字节Float表示数范围的原因,便是因为此类型转换的存在。
格式: 小范围变量类型 变量名 = (小范围变量类型) 大范围变量值
在将大范围变量的值存入小范围数据类型时,需要进行强制类型转换,这种转换是不安全的。强制类型转换可能会发生精度损失(比如将浮点数变为整数时),也可能会发生数据溢出(比如将200存入byte类型中数值会变为-56)。
对应自动类型转换,你有两千万,你想将钱存入最多能存放两百万的银行中,这时银行一定会问你,你确定吗?当然你想强行存入也是可以的,那么多出去的1800万自然就不再存在了,这便是溢出了,而你决定强行存入的过程就是对数据进行强制类型转换。
那么在Java中,基本数值型数据类型取值范围的大小为:
Double > Float > Long > Int > short > Byte
事实证明,浮点型确实厉害一点哦。
值得注意的是,byte、short、char在运算时会被自动提升为int型。