数值类型的运算方式总结

本文详细介绍了Java中的位运算(按位与、或、取反、异或及位移)及其应用场景,同时讨论了整数类型运算中的溢出问题及其解决方案,以及浮点类型运算中的精度丢失问题和使用BigDecimal进行高精度计算的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、常见的位运算使用场景

1.&(按位与):两个都为1,结果为1。

		//&运算:相同为1,不同为0
		int n1 = 2;//2的二进制数为:10
		int n2 = 3;//3的二进制数为:11
		int ret = n1&n2;//相与的结果为:10(二进制),转换为十进制为:2
		System.out.println(ret);//所以结果为:2(十进制)

2.|(按位或):只要有一个为1,则结果为1。

		//|运算:有1为1,无1为0
		int n1 = 2;//2的二进制数为:10
		int n2 = 3;//3的二进制数为:11
		int ret = n1|n2;//相或的结果为:11(二进制),转换为二进制为:3
		System.out.println(ret);//所以结果为:3(十进制)

3.~(按位取反):0变为1,1变为0。

		int n3 = 2;//2的二进制数为:0000 0010(原码)
		n3 = ~n3;        //取反后:1111 1101(补码)
		System.out.println(n3);//输出为十进制,也就是要将补码转换为原码
		//(1)如果补码的符号位为“0”,表示是一个正数,所以补码就是该数的原码。
		//(2)如果补码的符号位为“1”,表示是一个负数,求原码的操作可以是:符号位为1,各位取反,然后再整个数加1。
		//所以:
		//		n3的符号位为1,各位取反+1为:1000 0010 + 1 = 1000 0011;
		//所以1000 0011(二进制)再转换为十进制为:(最高位是符号位)-3;

4.^(按位异或):两边不同就为1。

		//^运算:不同为1,相同为0
		int n1 = 2;//2的二进制数为:10
		int n2 = 3;//3的二进制数为:11
		int ret = n1^n2;//异或的结果为:01(二进制),转换为二进制为:1
		System.out.println(ret);//所以结果为: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(十进制)

注意:

  • 只要涉及到‘位’,就涉及到二进制。
  • 整数之间可以进行位运算,浮点数之间不可以进行位运算。
二、整数类型运算时的类型溢出问题,产生原因以及解决办法。

产生原因:

基本数据类型都有自己的范围大小,在进行运算时,有时会超出整数类型表示的范围,导致溢出错误。

整形基本数据类型的范围:

byte:-128~+127

short:-32768~+32767

int:-2147483648~+2147483647(-2^31~+2^31-1)

long:-2^63~+2^63-1

解决办法:

1.当byte进行运算溢出时:可将结果的范围改为short、int、long等比byte范围大的类型。

		byte b1 = 127;
		byte b2 = 1;
		byte ret1 = (byte) (b1+b2);
		System.out.println("ret1="+ret1);

结果为:ret1=-128

  • 类型变为short后:
		byte b1 = 127;
		byte b2 = 1;
		short ret1 = (short) (b1+b2);
		System.out.println("ret1="+ret1);

结果为:  ret1=128

  • 类型变为int后:
		byte b1 = 127;
		byte b2 = 1;
		int ret1 = b1+b2;
		System.out.println("ret1="+ret1);

 结果为:ret1=128

  • 类型变为long后:
		byte b1 = 127;
		byte b2 = 1;
		long ret1 = b1+b2;
		System.out.println("ret1="+ret1);

  结果为:ret1=128

        以此类推,当short、int类型运算溢出时,都可以用比他们范围大的类型来表示结果类型。

2.当long类型运算溢出时:就要使用BigInteger来保存超大整数了,如下:

3.使用BigInteger保存超大整数:BigInteger支持大量的整数运算,包括加减乘除等等,它会将两个BigInteger对象的数组逐位进行运算,并将结果保存在新的BigInteger对象中,这种运算机制保证了BigInteger的运算精度和准确性。

public static void main(String[] args) {
		//使用BigInteger保存“超大整数”
		BigInteger n1 = new BigInteger("2123456789098765678978");
		BigInteger n2 = new BigInteger("9876543234567890678908");
		
		//通过调用方法,进行加减乘除运算
		//加法
		BigInteger sum = n1.add(n2);
		System.out.println(sum);
		
		//减法
		BigInteger sub = n2.subtract(n1);
		System.out.println(sub);
		
		//乘法
		BigInteger mul = n1.multiply(n2);
		System.out.println(mul);
		
		//除法
		BigInteger div = n2.divide(n1);
		System.out.println(div);
		
		//混合运算
		BigInteger n3 = new BigInteger("10");
		BigInteger ret = n3.multiply(n1).add(n2);
		System.out.println(ret);
		
	}

结果为:

12000000023666656357886
7753086445469124999930
20972412784270670442054681749751626003596024
4
31111111125555547468688

三、浮点类型运算时的精度丢失问题,产生原因以及解决办法。

产生原因:

因为计算机内部通过二进制的形式来保存浮点数,无法精确的表示十进制的小数,所以会产生经度丢失的问题。具体情况如下:

十进制的小数再进行二进制转换时,整数部分会除二取余,小数部分会乘二取整,在乘二取整的过程中,会产生无限循环的情况,所以就出现了精度丢失。

解决办法:

在进行大型金融等计算时,应该用BigDecimal类型,使用它的加减乘除方法俩进行计算。

		BigDecimal n1 = new BigDecimal("10.3");
		BigDecimal n2 = new BigDecimal("3.0");
		
		//加法
		BigDecimal sum = n1.add(n2);
		System.out.println(sum);  //输出为:13.3
		
		//减法
		BigDecimal sub = n1.subtract(n2);
		System.out.println(sub);  //输出为:7.3
		
		//乘法
		BigDecimal mul = n1.multiply(n2);
		System.out.println(mul);  //输出为:30.90
		
		//浮点数的除法运算容易产生无限循环:
		//可以用下图所示的三个参数的方法:
		//参数一:被除数
		//参数二:保留几位小数
		//参数三:小数位数的截取方式
		//RoundingMode.HALF_DOWN:代表四舍五入
		BigDecimal div = n1.divide(n2, 3,RoundingMode.HALF_DOWN);
		System.out.println(div);//输出为:3.433

在浮点数进行除法运算时,调用如下方法:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值