java浮点数计算机中储存方式以及进制转换

509 阅读4分钟

java浮点数计算机中储存方式

float类型 占据空间32位4字节

符号位(S):1bit指数位(E):8bit尾数位(M):23bit

double类型 占据空间64位8字节

符号位(S):1bit指数位(E):11bit尾数位(M):52bit

特别注意的是指数位存放的是补码,底数是2!

具体举例:

1.十进制转二进制

整数部分

十进制整数转二进制数:“除以2取余,逆序排列”(短除反取余法)

    • 例: 89(10) =10110012(2)
    • 除数被除数余数
      289
      2441
      2220
      2110
      251
      221
      210
      201

小数部分

十进制小数转二进制数:“乘以2取整,顺序排列”(乘2取整法)

    • 例: 0.625(10)= 0.101(2)
    • 乘数*乘数=整数
      0.625X2=1.251
      0.25X2=0.50
      0.5X2=1.01

转换结果

由上两步可知,89.625(10)转换为二进制位1011001.101(2)

在计算机中的储存方式

  • float f = 89.625f;

    • 计算符号位:因为为正数,所以符号位为 0。
    • 计算指数位:规范化表示小数点左边只能有一位并且为1,所以为1.011001101 x 26,规定指数位的底为2且幂加127(double类型加1023),所以指数位为133(127+6),转换为二进制——>1000 0101(2)。
    • 计算尾数位:规定尾数位去掉规范化前边的整数位的1,只保存小数,所以尾数位为 ——> 011001101
      最终得到的完整的浮点数为: 0 10000101 01100110100000000000000

符号位指数位尾数位
01000010101100110100000000000000

2.二进制转十进制

    • 例: 1011.01
    • (2)
    • =(1×2
    • 3
    • +0×2
    • 2
    • +1×2
    • 1
    • +1×2
    • 0
    • +0×2
    • -1
    • +1 × 2
    • -2
    • )
    • (10)
    • = (8+0+2+1+0+0.25) (10)
    • = 11.25 (10)

规律:个位上的数字的次数是0,十位上的数字的次数是1,…,依奖递增,而十分位的数字的次数是-1,百分位上数字的次数是-2,…,依次递减。

注意:不是任何一个十进制小数都能转换成有限位的二进制数。

数据类型强转

double in = 1.0256789123;	// in = 1.0256789123
float f = (float)in;		// f = 1.0256789; double 强转为float会造成精度丢失
int i = (int) f;			// i = 1;强转为 int类型 会丢失全部的小数位

强转注意:

值得引起注意的是: 浮点数强转,并不像整形强转那样,直接将数据一刀切

    • 例如:383
    • (10)
    • 对应的2进制为 0000 0001 0111 1111
      强转为byte类型
      值为127 (10) 对应的二进制位 0111 1111
      直接丢失高位字节

获取浮点数的整数位与小数位

获取浮点数的整数位

public int zhengshuwei(double in){
	return (int)in;
}

获取浮点数的小数位

public double xiaoshu(double in){
	int flag = (int)in;
	return in - flag;
}

若要将一个浮点数按其二进制强转为整形需调用其引用类型

long res = Double.doubleToLongBits(s);

根据其二进制获取数据的小数部分

	/**
	* @param s Double.doubleToLongBits(s);转过来的值
	* 即double数据对应的二进制的值
	*/
	public static double xiaoshu(long s) {
		int len = (int) ((s >>> 52 & 0x7ff )- 1023);//float - 127  >>> 23
		len = 52 - len;
		double res=0;
		for(int i=0-len;i<0;i++) {
			res += (s & 1) * Math.pow(2, i);
			s >>>= 1;
		}
		return res;
	}

根据其二进制获取数据的整数部分

	public static int zhengshu(long s) {
		int len = (int) ((s >>> 52 & 0x7fff )- 1023);//float - 127  >>> 23
		return (int) (((s & 0xfffffffffffffl) >> (52 - len)) + (1 << len));
	}