数值类型的运算方式总结

1.常见的位运算使用场景

        位运算是按照整数的二进制位进行移位、与、或、非、异或的运算,应用于整数类型(int),长整型(long),短整型(short),字符型(char),和字节型(byte)等数据类型(浮点型不能进行位算)。由于,位运算直接采用二进制进行计算,所以往往可以得到计算性能的提升。

1.1.移位运算 << 或 >>

5.<<(左移):各二进制位全部左移n位,左移翻倍。

//<<运算:各二进制位全部左移n位。左移翻倍
        int n1 = 2;//2的二进制数为:0010
        int n2 = 3;//3的二进制数为:0011
        int ret1 = n1<<2;//n1的二进制数(0010)向左移动2位:1000
        int ret2 = n2<<1;//n1的二进制数(0011)向左移动1位:0110
        System.out.println(ret1);//所以ret1结果为:8(十进制)
        System.out.println(ret2);//所以ret2结果为:6(十进制)


6.>>(右移):各二进制位全部右移n位,右移减半。

//>>运算:各二进制位全部右移n位。右移减半
        int n1 = 8;//2的二进制数为:1000
        int n2 = 6;//3的二进制数为:0110
        int ret1 = n1>>2;//n1的二进制数(1000)向左移动2位:0010
        int ret2 = n2>>1;//n1的二进制数(0110)向左移动1位:0011
        System.out.println(ret1);//所以ret1结果为:2(十进制)
        System.out.println(ret2);//所以ret2结果为:3(十进制)

1.2.与运算 &

&与运算的规则是:必须两个数同时为1,结果才为1

public class Main {
    public static void main(String[] args) {
        int i = 167776589; // 00001010 00000000 00010001 01001101
        int n = 167776512; // 00001010 00000000 00010001 00000000
        int x = i & n;     // 00001010 00000000 00010001 00000000
        System.out.println(x); // 167776512
    }
}

1.3.或运算 |

|或运算的规则是:只要任意一个为1,结果就为1

public class Main {
    public static void main(String[] args) {
       int i = 167776589;  // 00001010 00000000 00010001 01001101
       int n = 167776512;  // 00001010 00000000 00010001 00000000
       int x = i | n;      // 00001010 00000000 00010001 01001101
       System.out.println(x); // 167776589
    }
}

1.4.非运算 ~

~非运算的规则是:0和1互换(反转)

public class Hello {
	public static void main(String[] args) {
		int i = 167776589;  // 00001010 00000000 00010001 01001101
	    int x = ~i;         // 11110101 11111111 11101110 10110010
	    System.out.println(x); // -167776590
	}
}

 1.5.异或运算 ^

^异或运算的规则是:如果两个数不同,结果为1,否则为0。

public class Hello {
	public static void main(String[] args) {
		int i = 167776589; // 00001010 00000000 00010001 01001101
		int n = 167776512; // 00001010 00000000 00010001 00000000
		int x = i ^ n;     // 00000000 00000000 00000000 01001101
		System.out.println(x); // 77
	}
}

 1.6.常见用途

  • 移位运算,计算指定数值n的50%:n >> 1
  • 移位运算,计算指定数值n的2倍:n << 1
  • 与运算,判断奇偶数        a&1 == 0 偶数        a&1 == 1 奇数
  • 求平均值,防止溢出        (x&y)+((x^y)>>1)
  • 异或运算,交换两个整数

2.整数类型运算时的类型溢出问题,产生原因以及解决办法

2.1溢出原因

由于整数存在范围限制,如果计算结果超出了范围,就会产生溢出,而溢出不会出错,会得到一个奇怪的结果。

例如

public class Main {
    public static void main(String[] args) {
        int x = 2147483640;
        int y = 15;
        int sum = x + y;
        System.out.println(sum); // -2147483641
    }
}

解释上述结果:把整数2147483640和15换成二进制做加法,观察一下运算过程。

0111 1111 1111 1111 1111 1111 1111 1000
+ 0000 0000 0000 0000 0000 0000 0000 1111
-----------------------------------------
  1000 0000 0000 0000 0000 0000 0000 0111

由于最高位计算结果为1,因此,加法结果变成了一个负数。

2.3溢出解决方法

解决上面的问题,可以把int换成long类型,由于long可表示的整型范围更大,所以结果就不会溢出:

long x = 2147483640;
long y = 15;
long sum = x + y;
System.out.println(sum); // 2147483655

整形基本数据类型的范围

  • byte:-128~+127
  • short:-32768~+32767
  • int:-2147483648~+2147483647(-2^31~+2^31-1)
  • long:-2^63~+2^63-1

2.4用BigInteger表示任意大小的整数

如果我们使用的整数范围超过了long型,就要用数据结构来模拟一个大整数。java.math.BigInteger就是用来表示任意大小的整数。BigInteger内部用一个int[]数组来模拟一个非常大的整数:

BigInteger bi = new BigInteger("1234567890");

// 2867971860299718107233761438093672048294900000
System.out.println(bi.pow(5));

对做运算的时候,只能使用实例方法,例如,加法运算:

BigInteger i1 = new BigInteger("1234567890");
BigInteger i2 = new BigInteger("12345678901234567890");
BigInteger sum = i1.add(i2); // 12345678902469135780

BigInteger和long型整数运算比,BigInteger不会有范围限制,但缺点是速度比较慢。也可以把BigInteger转换成long型:

BigInteger i = new BigInteger("123456789000");
System.out.println(i.longValue()); // 123456789000
System.out.println(i.multiply(i).longValueExact()); // java.lang.ArithmeticException: BigInteger out of long range

使用longValueExact()方法时,如果超出了long型的范围,会抛出ArithmeticException。

BigInteger和Integer、Long一样,也是不可变类,并且也继承自Number类。因为Number定义了转换为基本类型的几个方法:

  • 转换为byte:byteValue()
  • 转换为short:shortValue()
  • 转换为int:intValue()
  • 转换为long:longValue()
  • 转换为float:floatValue()
  • 转换为double:doubleValue()

2.4.1BigInteger小结

  • BigInteger用于表示任意大小的整数
  • BigInteger是不变类,并且继承自Number父类
  • BigInteger转换成基本类型时可使用longValueExact()等方法保证结果准确,超出范围溢出时,会抛出ArithmeticException异常

  • 25
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值