当前位置: 首页 > 科技观察

如何使用二进制计算乘法?

时间:2023-03-16 18:57:25 科技观察

1.前言你是什么时候注意到位运算的?从毕业入职公司看到老板的代码出现2<<4开始?从小白到开放阅读框架源码,看MAXIMUM_CAPACITY=1<<30;开始?或者从什么时候开始?其实二进制位运算一直就在我们身边。当你开始编写HelloWord打印输出时,就有二进制流处理,但它隐藏得很深,很难找到。所以当我们开始意识到代码和二进制之间的关系时,往往来自于看到可以用二进制完成的计算,包括;二进制计算比乘法更高效,二进制更能体现你要设置的值的大小范围。比如你要设置一个指定范围size=1073741824的Int值,那么给这样的整数值是直观,还是给二进制1<<30更直观?其实这两个值是相等的。所以在这种情况下,也会有二元运算的表现。小付在学习编程的时候,第一次注意到二元运算就是关于a和b两个值的交换。如果不引入第三个值就可以完成呢?inta=2,b=3;a=a^b;b=a^b;a=a^b;同一个帽子的^运算符,替换两个数,替换后a=3,b=2那么它是怎么做到的呢?^异或运算:在两个操作数相同的位置,如果值相同(都为0或者都为1)则为0,如果不同(一个为0,另一个为1),则为1.根据二进制数据进行运算分析a=2二进制数为0010,b=3二进制数为0011a=a^b=0010^0011=0001b=a^b=0001^0011=0010=2a=a^b=0001^0010=0011=3不同OR运算的基本定理是a=a^bb=a^b=a^b^b=a=2a=a^b=a^a^b=b=3而二进制运算的魅力远不止于此,它还可以完成奇偶判断、有效位计算、乘法、加法等。这些内容的学习可以让我们的研发人员积累编程逻辑,拓展思维方式.接下来付哥就带大家学习一下。2.位运算简介位运算是编程中对位数组或二进制数的一元和二元运算。在许多较旧的微处理器上,按位运算比加法和减法稍快,通常比乘法和除法快得多。在现代架构上,位运算通常以与加法相同的速度执行(仍然比乘法快),但由于资源使用减少,通常消耗更少的功率。四种基本位操作包括;AND&,OR|,NOT^,XOR~inta=1;//0001intb=2;//0010intc=4;//0100intd=8;//1000inte=15;//1111//与运算;0001System.out.println(Integer.toBinaryString(a&e));//0001//或运算;0011System.out.println(Integer.toBinaryString(a|b));//0011//非操作;0101System.out.println(Integer.toBinaryString(a^c));//0101//异或运算;...11110111System.out.println(Integer.toBinaryString(~d));和操作;两个数都转换成二进制,然后从高位开始比较,如果两个数都为1,则为1,否则为0。或运算;两个数都转换成二进制,然后从高位开始比较,只要两个数中有一个为1,则为1,否则为0。不运算;将两个数转化为二进制,然后从高位开始比较,相同则为0,不相同则为1。异或运算;如果该位为0,则结??果为1,如果该位为1,则结果为0III.位操作案例1.获取位值publicintgetBit(intnumber,int{return(number>>bitPosition)&1;}目的:获取二进制数中指定位置的值逻辑:该方法移动目标取最右边的值,也就是位数组的第0位,比如0001的二进制形式,然后和1做AND运算。如果目标位为1,则结果为1,否则结果为0;2.设置位值publicintsetBit(intnumber,int{returnnumber|(1<>31)&1)==0;}目的:判断number的值是否为正数。逻辑:根据二进制正数最左边的值为0,右移31位,与1进行与运算,结果等于1则为负数,为无论如何都是正数。7.左移两位publicintmultiplyByTwo(int{returnnumber<<1;}目的:乘以2逻辑:该方法将原数左移一位。所以所有位都会乘以2,所以数本身会乘以2。8.右移两个publicintdivideByTwo(int{returnnumber>>1;}目的:除以2逻辑:该方法将原数右移一位。所以所有位将被除以2,因此数字本身也将除以2而没有余数。9、正负交换publicintswitchSign(int{return~number+1;}目的:正数转负数,负数转正数逻辑:通过二进制异或运算取反,如1000=8取反1.....0111=-9+1=-810.乘法(有符号)publicintmultiply(inta,int{intmultiply=0;while(a!=0&&b!=0){System.out.print("计算步骤("+(isEven(b)?"Even":"Odd")+"):a("+String.format("%04d",Integer.valueOf(Integer.toBinaryString(a)))+")="+a+"|b("+String.format("%04d",Integer.valueOf(Integer.toBinaryString(b)))+")="+b);//b是偶数:2a*(b/2)if(isEven(b)){a=multiplyByTwo(a);b=divideByTwo(b);}//b是奇数else{//b是正数:2a*(b-1)/2+aif(isPositive(b)){multiply+=a;a=multiplyByTwo(a);b=divideByTwo(b-1);}//b为负数:2a*(b+1)/2-aelse{multiply-=a;a=multiplyByTwo(a);b=divideeByTwo(b+1);}}System.out.println("|multiply("+String.format("%04d",Integer.valueOf(Integer.toBinaryString(multiply)))+")="+multiply);}returnmultiply;}目的:计算有符号二进制乘积公式:将公式对应推码=a*b=2a*(b/2)——b为偶数=2a*(b-1)/2+a——b为奇数,正数=2a*(b+1)/2-a——b为奇数,负数逻辑:乘数a不断左移,乘数b一直向右移动。当b归0时,a左移累加的值就是乘积之和。图11.乘法运算(无符号)publicintmultiplyUnsigned(intnumber1,int{intresult=0;intmultiplier=number2;intbitIdx=0;while(multiplier!=0){if((multiplier&1)==1){System.out.println(number1+"<<"+bitIdx+"="+(number1<>1;}returnresult;}目的:计算无符号二进制乘积公式:13=2^3+2^2+2^0x13=x2^3+x2^2+x2^0x*13=x<<3+x<<2+x<<02*13=2<<3+2<<2+2<<0=16+8+2=26逻辑:每个数字都可以表示为一系列2的幂和。例如13的二进制值是1101,右边第一位是1,是2的次方,所以对应的二进制值2要左移0。比如右边第三位13是1,对应位置值4是2的2次方,所以把2对应的基值左移2位,最后加上这些价值就是产品价值。12.publicintcountSetBits(int{intsetBitsCount=0;intnumber=originalNumber;while(number!=0){setBitsCount+=number&1;number>>>=1;}returnsetBitsCount;}目的:使用位运算符对一个数中设置为1的位进行计数逻辑:每次将数向右移动1位,然后使用&运算符取出最右边位的值。1计数加1,0计数13.转换计算publicintbitsDiff(intnumber1,int{returncountSetBits(number1^number2);}目的:计算一个数转换为另一个数需要的位数。逻辑:当对数进行异或运算时,结果将是不同位数的个数(即异或结果中设置为1的位数)14.有效位数publicintbitLength(int{intbitsCounter=0;while((1<