深入浅出系列之JAVA基本类型及位运算

原码、反码和补码

原码,反码,补码的产生过程,就是为了解决,计算机做减法和引入符号位(正号和负号)的问题。

原码

*原码:*是最简单的机器数表示法。用最高位表示符号位,‘1’表示负号,‘0’表示正号。其他位存放该数的二进制的绝对值。

反码

反码:正数的反码还是等于原码;负数的反码就是他的原码除符号位外,按位取反。

补码

补码:正数的补码等于他的原码 负数的补码等于反码+1。 (这只是一种算补码的方式)

移码

移码(又叫增码)是符号位取反的补码,一般用指数的移码减去1来做浮点数阶码,引入的目的是为了保证浮点数的机器零为全0。

计算机加减流程及原理

计算机只有加法器 -> 正数和负数的加减运算 ->转化为补码进行加法运算 ->补码运算的原理在于取负数的同余数进行加法运算

补码运算规则

[原码] + [原码] -> [补码]+[补码] = [补码] -> [原码](结果)

位运算核心知识点

  • 位运算操作的是整数
  • 计算机中,整数以机器数补码的形式存储
  • 位运算操作的是整数的二进制补码

位运算

  • 位运算只可以处理整数类型(byte、short、int、long)

  • 位运算操作的是整数的二进制补码

  • 位运算对byte和short进行移位操作时,在移位之前,会被转换成int类型,得到的结果也是int类型

位运算规则
位运算符说明
&
|
^异或
按位取反
<<左移运算符,符号位不变,右侧低位补0,左侧高位舍弃。向左移动指定位数,一般情况下每移动一位都会乘以2(除符号位之外,最高位不为1的情况下,高位为1时,超过了位数限制)
>>右移运算符,符号位不变,右侧低位舍弃,左侧高位正数补0,负数补1。向右移动指定位数,一般情况下每移动一位都是除以2(低位为1时,会丢失精度)
>>>按位右移补零操作符,无论正负,右侧低位舍弃,左侧高位插入0

位运算符操作的都是补码,尤其是负数移位操作,应该深刻认识操作的是负数的二进制补码!!!

JAVA基本类型的默认值和取值范围

默认值存储需求(字节)取值范围示例
byte01-27—27-1byte b=10;
short02-215—215-1short s=10;
int04-231—231-1int i=10;
long08-263—263-1long o=10L;
float0.0f4IEEE754float f=10.0F
double0.0d8IEEE754double d=10.0;
booleanfalse1true\falseboolean flag=true;
char‘ \u0000′20—2^16-1char c=’c’ ;

int类型和byte数组的相互转化

/** 
 * int到byte[] 
 * @param i 
 * @return 
 */  
public static byte[] intToByteArray(int i) {  
    byte[] result = new byte[4];  
    // 由高位到低位  
    result[0] = (byte) ((i >> 24) & 0xFF);  
    result[1] = (byte) ((i >> 16) & 0xFF);  
    result[2] = (byte) ((i >> 8) & 0xFF);  
    result[3] = (byte) (i & 0xFF);  
    return result;  
}  
  
/** 
 * byte[]转int 
 * @param bytes 
 * @return 
 */  
public static int byteArrayToInt(byte[] bytes) {  
    int value = 0;  
    // 由高位到低位  
    for (int i = 0; i < 4; i++) {  
        int shift = (4 - 1 - i) * 8;  
        value += (bytes[i] & 0x000000FF) << shift;// 往高位游  
    }  
    return value;  
}  
  
public static void main(String[] args) {  
    byte[] b = intToByteArray(128);  
    System.out.println(Arrays.toString(b));  
      
    int i = byteArrayToInt(b);  
    System.out.println(i);  
}

位运算代码

	public static void testBitOperation() {
		//数值在机器中以补码的形式存储,位运算规则操作的是数值的二进制补码
		int positive = 2;  //0... 0000 0010(原码) 0... 0000 0010(反码)  0... 0000 0010(补码)
		int negative = -2; //1... 0000 0010(原码) 1... 1111 1101(反码)  1... 1111 1110(补码)
	       
		System.out.println("positive:" + positive);
		System.out.println("negative:" + negative);
		System.out.println("&:" + (positive & negative));//0... 0000 0010(补码)  0... 0000 0010(反码)  0... 0000 0010(原码) 
		System.out.println("|:" + (positive | negative));//1... 1111 1110(补码)  1... 1111 1101(反码)  1... 0000 0010(原码)
		System.out.println("~positive:" + ~positive);//1... 1111 1101(补码) 1... 1111 1100(反码)  1... 0000 0011(原码)
		System.out.println("~negative:" + ~negative);//0... 0000 0001(补码) 0... 0000 0001(反码)  0... 0000 0001(原码)   
		System.out.println("^:" + (positive ^ negative));//1... 1111 1100(补码)  1... 1111 1011(反码)  1... 0000 0100(原码)
		
		System.out.println("positive << 3:" + (positive << 3));//0... 0001 0000(补码) 0... 0001 0000(反码) 0... 0001 0000(原码)
		System.out.println("negative << 3:" + (negative << 3));//1... 1111 0000(补码) 1... 1110 1111(反码) 1... 0001 0000(原码)
		
		System.out.println("positive >> 3:" + (positive >> 3));//0... 0000 0000(补码) 0... 0000 0000(反码) 0... 0000 0000(原码)
		System.out.println("negative >> 3:" + (negative >> 3));//1... 1111 1111(补码) 1... 1111 1110(反码) 1... 0000 0001(原码)
		
		
		System.out.println("positive >>> 3:" + (positive >>> 3));//0... 0000 0000(补码) 0... 0000 0000(反码) 0... 0000 0000(原码)
		System.out.println("negative >>> 3:" + (negative >>> 3));//0001 1111 1111 1111 1111 1111 1111 1111(补码\反码\原码) 
		System.out.println("negative >>> 3:" + Integer.parseInt("00011111111111111111111111111111", 2));
	}


/**output**/
positive:2
negative:-2
&:2
|:-2
~positive:-3
~negative:1
^:-4
positive << 3:16
negative << 3:-16
positive >> 3:0
negative >> 3:-1
positive >>> 3:0
negative >>> 3:536870911
negative >>> 3:536870911

float类型和double类型

符号位阶码尾数长度
float182332
double1115264
float和double计算方式

float和double取值范围和精度问题
  • float和double的取值范围是由指数的位数来决定的

  • float的指数范围为-27~27-1(即-128127),而double的指数范围为-2^102^10-1(即-1024~1023)

  • float的范围为-2^128 ~ +2^128(-3.40E+38 ~ +3.40E+38)

  • double的范围为-2^1024 ~ +2^1024(-1.79E+308 ~ +1.79E+308)

  • float和double的精度是由尾数的位数来决定的

  • float:2^23 = 8388608,一共七位,这意味着最多能有7位有效数字,即float的精度为6~7位有效数字;

  • double:2^52 = 4503599627370496,一共16位,同理,double的精度为15~16位。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值