数值类型的运算方式总结

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

注意:位运算按照整数的二进制位进行计算,二进制数最高位(最左边数字)为符号位,最高位为0表示正数,最高位为1表示负数

  • 移位运算   <<  或  >>
名称运算规则使用场景举例
<<左移运算符

对整数n进行左移运算,等同于将整数n放大2^{m}倍,m为位移数

n<<1 :计算整数n的二倍;

n=3

n<<1 等同于 

        n\times2^{1}= 3\times2^{1} =6

n<<2 等同于 

        n\times2^{2}= 3\times2^{2} =12

>>右移运算符对整数n进行右移运算,等同于将整数缩小2^{m}倍,m为位移数n>>1 :计算整数n的一半;

n=12

n>>1 等同于 n\div2^{1}= 12\div2^{1} =6

n>>2 等同于 n\div2^{2}= 12\div2^{2} =3

简记:左移执行乘法,右移执行除法

程序为:

class Main {
  public static void main(String[] args) {
    int a=3,b=12,a1,a2,b1,b2;
    //定义a,b,a1,a2,b1,b2为整数类型;a、b分别赋初值为值3和12;其它默认初值为0
    //3的二进制表示为00000000 00000000 00000000 0000000011;
    //12的二进制表示为00000000 00000000 00000000 0000001100;
    //0的二进制表示为00000000 00000000 00000000 0000000;
    
    a1=a<<1;//a1为a进行左移一位的运算结果
    //3左移一位的二进制表示为00000000 00000000 00000000 0000000110,
    //转换成十进制结果为6

    a2=a<<2;//a2为a进行左移两位的运算结果
    //3左移两位的二进制表示为00000000 00000000 00000000 0000001100,
    //转换成十进制结果为12

    b1=b>>1;//b1为b进行右移一位的运算结果
    //12右移一位的二进制表示为00000000 00000000 00000000 0000000110,
    //转换成十进制结果为6

    b2=b>>2;//b1为b进行右移两位的运算结果
    //12右移两位的二进制表示为00000000 00000000 00000000 0000000011,
    //转换成十进制结果为3

    System.out.println("整数a左移一位的结果为:a1="+a1);
    System.out.println("整数a左移两位的结果为:a2="+a2);
    System.out.println("整数b右移一位的结果为:b1="+b1);
    System.out.println("整数b右移两位的结果为:b2="+b2);
  }
}

运行结果为:

  • 与运算    &

与运算规则:两个数的二进制对应位数字同时为1,结果才为1

整数对应二进制数
200000000 00000000 00000000 00000010
300000000 00000000 00000000 00000011
2&300000000 00000000 00000000 00000010(转换成十进制结果为2)

程序为:

class Main {
  public static void main(String[] args) {
    int a=2,b=3,c;//定义整数a,b,c;a,b分别赋予初值为2和3;c默认值为0
    c=a&b;//c为a与b进行与运算的结果
    System.out.println("整数a与b进行与运算的结果c为:c="+c);
  }
}

运行结果为:

与运算使用场景
判断奇偶数求平均值(防止溢出)
a&1==0  偶数a&1==1  奇数

(x&y)+((x^y)>>1)(^为异或运算符,下面会讲到)

判断奇偶数程序为:

class Main {
  public static void main(String[] args) {
    int a=2;//定义一个偶数的整数,赋值为2
    int b=3;//定义一个奇数的整数,赋值为3
    int c,d;//定义两个整数,默认初值为0
    c = a & 1 ;
    d = b & 1 ;
    System.out.println("偶数a与1做与运算的结果为c="+c);
    System.out.println("奇数b与1做与运算的结果为d="+d);
  }
}

运行结果为:

判断奇偶数原理如下:1的二进制为00000000 00000000 00000000 00000001,是奇数;

一个偶数的二进制最右边位数一定是为0;

二进制相同位数同时为1时,结果才为1;

若一个偶数与1做与运算,结果的二进制数的数字一定为0

若一个奇数与1做与运算,结果的二进制数的数字一定为1

求平均值(防止溢出)程序为:

class Main {
  public static void main(String[] args) {
    int x = 2 , y = 4 , z ;//定义整数x,y,z;x,y的初始值分别为2和4,z默认为0
    z = ( x & y ) + ( ( x ^ y) >> 1 ) ;//利用位运算方法求x和y的平均值z
    System.out.println("x和y的平均值z="+z);
  }
}

运行结果为:

  • 或运算   |

或运算规则:两个数的二进制对应位数字只要有一个为1,结果就为1

整数对应二进制数
200000000 00000000 00000000 00000010
300000000 00000000 00000000 00000011
2 | 300000000 00000000 00000000 00000011(转换成十进制结果为3)

程序为:

class Main {
  public static void main(String[] args) {
    int a=2,b=3,c;//定义整数a,b,c;a,b分别赋予初值为2和3;c默认值为0
    c=a | b;//c为a与b进行或运算的结果
    System.out.println("整数a与b进行或运算的结果c为:c="+c);
  }
}

运行结果为:

  • 非运算   ~

非运算规则:整数的二进制位0与1互换(0变成1,1变成0)

整数对应二进制数
200000000 00000000 00000000 00000010
~2111111111 111111111 111111111 111111101(转换成十进制数字为 -3)

程序为:

class Main {
  public static void main(String[] args) {
    int a=2,c;//定义整数a,c,a赋予初值为2,c默认值为0
    c= ~a;//c为a进行非运算的结果
    System.out.println("整数a进行非运算的结果c为:c="+c);
  }
}

运行结果为:

  • 异或运算   ^

异或运算规则:两个数的二进制对应位数字不同,结果就为1

整数对应二进制数
200000000 00000000 00000000 00000010
300000000 00000000 00000000 00000011
2 ^ 300000000 00000000 00000000 00000001(转换成十进制结果为1)

程序为:

class Main {
  public static void main(String[] args) {
    int a=2,b=3,c;//定义整数a,b,c;a,b分别赋予初值为2和3;c默认值为0
    c=a ^ b;//c为a与b进行异或运算的结果
    System.out.println("整数a与b进行异或运算的结果c为:c="+c);
  }
}

运行结果为:

异或运算使用场景:进行两个数的交换

如:a=2,b=3;通过三次异或运算【a=a^b;b=a^b;a=a^b】,可以得到a=3,b=2

程序为:

class Main {
  public static void main(String[] args) {
    int a=2,b=3;//定义整数a,b,c;a,b分别赋予初值为2和3;

    //a与b做三次异或运算
    a = a ^ b;
    b = a ^ b;
    a = a ^ b;
    System.out.println("整数a为:a="+a);
    System.out.println("整数b为:b="+b);
  }
}

运行结果为:

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

整数类型 int型 进行计算时的类型溢出问题
产生原因解决办法

整数存在范围限制(整数范围为 -2147483648

~2147483647)计算结果超出这个范围,就会产生溢出,这个溢出不会出错,只是结果比较奇怪

方法一:int型进行类型转换成 long型,long型可表示的整形范围更大,结果就不会溢出了

【 long型范围为 -9223372036854775808~9223372036854775807 】

方法二:使用BigInteger,BigInteger不会有范围限制(但相对于long型的运算,计算速度降低),BigInteger表示任意大小的整数,BigInteger做运算,只能使用实例方法

程序为:

import java.math.BigInteger;
class Main {
  public static void main(String[] args) {
   int a = 2147483647;//定义整数a,赋值为int类型最大值
   int b = 14;//定义整数b,赋值为14
   int c = a+b;//计算a与b的和c[int型]
   
   System.out.println("[int型]计算a与b的和c="+c);//结果为负值,不正确;
   //因为类型溢出了

   //解决类型溢出问题
   //方法一:int型进行类型转换成 long型 
   long d = (long)a+b;//计算a与b的和c[long型]
   System.out.println("[long型]计算a与b的和d="+d);//结果正确

   //方法二:使用BigInteger
   BigInteger e = new BigInteger("2147483647");//定义整数e,与a大小一致
   BigInteger f = new BigInteger("14");//定义整数f,与b大小一致
   System.out.println("[BigInteger型]计算e与f的和,结果为"+e.add(f));//结果正确
  }
}

运行结果为:


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

浮点类型运算时的精度丢失问题
产生原因解决办法
由于浮点数属于小数范围,小数换算成二进制会出现无限循环小数,计算机不能显示出无限位数的小数,只能取近似值显示,就会造成浮点数无法精确表示的情况,就会出现精度丢失问题

使用BigDecimal,BigDecimal与BigInteger类似,它可以表示一个任意大小且精度完全准确的浮点数

程序为:

import java.math.BigDecimal;//导入java.Math.BigDecimal包
class Main {
  public static void main(String[] args) {
    double a = 1.0;//定义浮点数a=1.0
    double b = 0.9;//定义浮点数b = 0.9
    double c = a-b;//定义浮点数a与b的差c
    System.out.println("浮点数a与b的差为c="+c);//精度丢失,结果不正确

    BigDecimal d = new BigDecimal("1.0");//定义BigDecimal类型浮点数d,与a值相同
    BigDecimal e = new BigDecimal("0.9");//定义BigDecimal类型浮点数e,与b值相同
    System.out.println("浮点数d与e的差为: "+d.subtract(e));//结果正确
  }
}

运行结果为:

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值