按照常理来说:
int和float都是32位,都能表示2^32个数,
所以能表示的个数是一样多的。float能表示的范围比int能表示的范围要大。
一.int类型分析
- int用4字节保存,最多表示2^32,包含正负数。
- 可以表示2^31-1个正数,最大值为2147483647,最小值为-2147483648,0占一个正数的名额
- 为了计算机方便计算,负数在计算机中储存的是补码(无需再管符号位,可以让符号位直接参与运算)
原码 ===除了符号位,其他取反===> 反码 ===加1===> 补码
二.float分析
1.float用4字节保存,为single单精度
2.存储结构:符号位、指数位、位数位
例:请写出165.25(10进制)使用float型存储在计算机中的形式。
- 转换为2进制:165.2510⇒ 1010 0101 . 0100
- 规范二进制小数的表示形式 1010 0101 . 0100 => 1.01001010100 * 2^7
IEEE754标准做了这样的规定:当尾数(小数)不为0时,尾数域的最高有效位为1,这称为浮点数的规格化。
- 规格化之后,我们只需要存储一个尾数(即小数部分,整数部分恒为1)和指数部分。其中包含了1位符号位S,8位阶码E和23位尾数M。
- 要存储这个二进制小数;
- 首先符号位S,0表示正数,1表示负数。S=0;
- 再写出尾数M,即:M=0100 1010 1000 0000 0000 000;
- 然后算出阶码E,这里指数为:e=7=0000 0111,根据标准要求,E=e+127;
- 即:E=7+127=134=1000 0110;
3.浮点数的表示范围有多大?
float型定义的正无穷大
float型定义的负无穷大
得出当E= 1111 1111时,指数为255-127=128,但这并不是表示这个数是: 1×2128 ,在IEEE754把这种情况定义为无穷大,此时尾数必须全部为0,不能有其他值,否则就认为无效数字(NaN)。
- float能表示的最大值: 2^128-2^104
- float能表示的最小值: 2^104-2^128
4.为什么要用指数加上127,才是阶码E,而不是直接用指数存进去?
我们希望存储到机器里的阶码永远都是正值,因为我们不希望再浪费一个坑去保存阶码的正负号,于是把指数加上127,而指数能取到的最小值就是-127,这样就可以保证阶码E永远都是正数,就不用再考虑指数正负号的问题了。
5、这个过程可以看出float有效位是尾数M加1也就是24位,阶码E只是我们用于规范科学计数法记录指数的,但int有效位是32位,float实际有效位比int少,那么在相互转换的过程中会出现什么问题?
- float型的表示范围是比int大很多的,但有效位确实只有24位。既然float范围大,那么所有的int型都是可以转换为float型的,这是不会产生溢出报错的。
- 但因为int型有效位是32位,是比float型的24位大的,是有可能发生舍入,即当一个int型数字,转成float型后,可能就不再是原本数字了,损失了一定的精度。
如果8位指数位全为0, 就代表当前数是个非规格数. 或者说, 形如 * 00000000 *********************** 格式的数就是非规格数。
如果8位指数位全为1, 就代表当前数是个特殊数. 或者说, 形如 * 11111111 *********************** 格式的数就是特殊数。
如果8位指数不全为0, 也不全为1(也就是除去以上两种状态外, 剩下的所有状态), 这个数就是规格数。
总结:
- 虽然都是32位,float表示范围比int的范围更大,但是精度不足。
- float因为IEEE754标准,需要区分非规格化数、规格化数(常见)、特殊数。特殊数分为正负无穷,和NaN(数量为2^24)。而int能够直接对应十进制数,所以int表示的数比float多。