位操作实现四则运算!!!Say Bye To + - * /

Java位操作实现四则运算:

位操作技巧:

>>> 逻辑移位符,如:num>>>n 则表示向右移动n位,高位补0
>> 算数移位符,不同的是正数高位补0,负数高位补1
<< 移位符,像左移动n位,低位补0
注意:逻辑取反是把非零变为零,把零变为一。~表示按位取反,把1变为0,把0变为1.

  • 计算机中存储数的形式是二进制补码,其包括符号位与数值位,其中符号位为0表示正数,符号位为1表示负数。
  • 并且正数的原码、反码和补码都相同。而负数是符号位为1的二进制字符串,且:补码=原码取反+1(符号位不变)
  • 例如:java中byte类型3二进制表示0000 0011,若取反有1111 1100.由于第一位是1,将3取反后理解为一个负数的补码,反推该补码的原码,则该补码减去1为1111 1011再取反为0000 0100,其原码表示的是4,则说明该补码表示-4.
    System.out.println(~3);//输出值为-4.
    
  • 更通用的,假设n是一个正数,那么~n=-(n+1).我们也可以从补码的定义去理解这个等 式,原码n,取反为~n,加1为~n+1为补码,即~n+1表示-n,那么有~n=-(n+1)
  • 获取正数n的二进制串最后一个1:~(n-1)&n=-n&n
  • 去掉整数n的二进制串中最后一个1:n&(n-1)
代码实现:
class ControlBitsForAddMinusMultiDiv {
	public int add(int a,int b) {
        int res=a;
        int xor=a^b;//得到原位和,按位相加后没有进位的和
        int forward=(a&b)<<1;//得到进位和
        if(forward!=0){//若进位和不为0,则递归求"原位和"加上"进位和"
            res=add(xor, forward);
        }else{
            res=xor;//若进位和为0,则此时原位和为所求和
        }
        return res;
    }
	public int minus(int a,int b) {//默认b大于0
        int B=~(b-1);//由~n=-(n+1)将减法转换为加法,此处相当于求的是正数b的补码,也就是-b
        return add(a, B);        
    }
	public int multi(int a,int b){
        int i=0,res=0;
        while(b!=0){//乘数为0则结束
            //处理乘数当前位
            if((b&1)==1){
                res+=(a<<i);//此处及后面的加减法可以用我们的add方法和minus方法替换!
                b=b>>1;
                ++i;//i记录当前位是第几位
            }else{
                b=b>>1;
                ++i;
            }
        }
        return res;
    }
	public int sub(int a,int b) {
        int res=-1;
        if(a<b){
            return 0;
        }else{
            res=sub(minus(a, b), b)+1;//除法是递归的减法!
        }
        return res;
    }
	private static void binaryToDecimal(int n) {//将十进制数转为对应的二进制数
		for(int i=31;i>=0;i--) {
			System.out.print(n>>>i&1);
		}
		System.out.println();
	}
	//上述除法会爆栈,当被除数远大于除数的时候!
	//Exception in thread "main" java.lang.StackOverflowError
	//所以除法应当是除法操作更优,而非减法的递归!!!
	public int divide(int dividend, int divisor) {
		//if(dividend>2>>31-1||dividend<-2<<31||divisor>2>>31-1||divisor<-2<<31) {return 2>>31-1;}
	
		//if(dividend>Integer.MAX_VALUE||dividend<Integer.MIN_VALUE||divisor>Integer.MAX_VALUE||divisor<Integer.MIN_VALUE) {return Integer.MAX_VALUE;}
		boolean symbol=true;
		long d=dividend,b=divisor,count=1,result=0;
		if(dividend<0){d=-d;symbol=!symbol;}
		if(divisor<0){b=-b;symbol=!symbol;}
		long tmp=b;
		while(d-b>=0) {
			while(d-tmp>=0) {
				tmp=tmp<<1;
				count=count<<1;
				}
			tmp=tmp>>1;
			count=count>>1;
			d-=tmp;
			result+=count;
			tmp=b;
			count=1;
			}
	   if(!symbol) {
	       if(-result<Integer.MIN_VALUE)return Integer.MAX_VALUE;
	        	return (int) -result;
	        }
	   if(result>Integer.MAX_VALUE)return Integer.MAX_VALUE;
	        return (int) result;
	    }
	public int divideNew(int dividend, int divisor) {
		long a=(long)dividend,b=(long)divisor,res=0;
		if(a<0)a=-a;
		if(b<0)b=-b;
		for(int i=32;i>=0;i--) {
			if(a>>i>=b) {//被除数的右移相当于是除数的借位左移!
				res+=1l<<i;//此处注意类型!
				a-=b<<i;
			}
		}
		res=(dividend>0)==(divisor>0)?res:-res;
		if(res>Integer.MAX_VALUE||res<Integer.MIN_VALUE)return Integer.MAX_VALUE;
			return (int)res;
		}
	public static void main(String[] args){
		
		binaryToDecimal(3);
		binaryToDecimal(-4);
		binaryToDecimal(127);
		binaryToDecimal(-128);
		
		ControlBitsForAddMinusMultiDiv t = new ControlBitsForAddMinusMultiDiv();
		System.out.println(t.add(1, 2));
		System.out.println(t.minus(1, 2));
		System.out.println(t.multi(1, 2));
		System.out.println(t.sub(3, 2));
		System.out.println(t.divide(2147483647, -1));
		System.out.println(t.divideNew(2147483647, -1));
		}
}
Java的基本类型:
在Java中一共有8种基本数据类型(1byte=8bits)

4种整型:
byte 1字节 -128~127(-2^7 ~ 2^7-1) 一共8bits,第一位是符号位,则1000 0000(-128) ~ 0111 1111(127)
short 2字节 -32768~32767
int 4字节 -2147483648~2147483647
long 8字节 -9223372036854775808 ~ 9223372036854775807(-2^31 ~ 2^31-1)
2种浮点类型:
float 4字节 -3.4E38~3.4E38
double 8字节 -1.7E308~1.7E308
1种用于表示Unicode编码的字符单元的字符类型:
char2字节 从字符型对应的整型数来划分,其表示范围是0~65535
1种用于表示真值的boolean类型:
boolean 1bit或者1个字节或者4个字节? true或false
boolean大小的说明:
常规理解,空间应该越小越好,所以1bit是不是就够用了啦!
但是JVM考虑处理速度的问题,32bits更舒服,也就是int类型处理性能更好!
而在boolean数组的存储上采用byte类型,即每个数组使用8bits.

java没有无符号类型
	 * 在c语言中,有符号字符型(signed char),占一个字节,长度范围为-128 ~ 127
	 * 而无符号字符型(signed char),也占一个字节,长度范围为0 ~ 255
	 * 
	 * 在java中没有无符号类型,但可以通过位运算得到对应的无符号类型。
	 * 例如:
	 * byte b=-1;对应的补码为:1111 1111
	 * 则:b&0x0FF则为其对应的无符号值!即255.
		 byte b = -1;
		 System.out.println(b&0x0FF);
相关参考:
位操作实现四则运算:
补码的意义? 为了用加法操作表示减法运算,减去一个正数相当于加上这个数的对应的补码。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值