写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
位运算实现加法:
- int AddWithoutArithmetic(int num1,int num2)
- {
- if(num2==0) return num1;
- int sum,carry;
- sum=num1^num2;
- carry=(num1&num2)<<1;
- return AddWithoutArithmetic(sum,carry);
更简洁的形式如下:
- public classAddWithoutArithmetic{
- {
- public int Add(int num1,int num2) {
- int result = (num2 != 0 ? Add(num1^num2,(num1 & num2)<<1) : num1);
- return result;
-
-
算法思想解析:
在不使用四则运算做加法运算的情况下我们会很自然地就会去考虑使用二进制数的位运算;
位运算的过程我们将其分为两个步骤:
1)只管各位数对应相加,不考虑进位的影响;
2)将运算过程中的进位影响考虑进来,这时候又回到上个步骤的循环之中,进位产生的数和sum再求和,其过程又分为两个步骤,即
不考虑进位各位相加,然后再加上进位数。
由此看来,整个过程就是一个循环迭代的过程!
非递归的版本如下:
- int Add(int a, int b)
- {
- int ans;
- while(b)
- {
- ans = a^b;
- b = ((a&b)<<1);
- a = ans;
- }
- return a;
- }
---------------------------------------------------------------------------------------------------------------------------------------------------------
减法运算:
-
- int negtive(int a)
- {
- return Add(~a, 1);
- }
- int Sub(int a, int b)
- {
- return Add(a, negtive(b));
- }
---------------------------------------------------------------------------------------------------------------------------------------------------------
正数乘法运算:
-
- int Pos_Multiply(int a,int b)
- {
- int ans = 0;
- while(b)
- {
- if(b&1)
- ans = Add(ans, a);
- a = (a<<1);
- b = (b>>1);
- }
- return ans;
- }
----------------------------------------------------------------------------------------------------------------------------------------------------------
整数除法(正整数)
-
- int Pos_Div(int x,int y)
- {
- int ans=0;
- for(int i=31;i>=0;i--)
- {
-
- if((x>>i)>=y)
- {
- ans+=(1<<i);
- x-=(y<<i);
- }
- }
- return ans;
- }
-------------------------------------------------------------------------------------------------------------------------------------------------------
完整的实现:
-
-
-
-
- #include<iostream>
- #include<cstdio>
- using namespace std;
-
- int Add(int a, int b)
- {
- int ans;
- while(b)
- {
- ans = a^b;
- b = ((a&b)<<1);
- a = ans;
- }
- return a;
- }
-
-
- int negtive(int a)
- {
- return Add(~a, 1);
- }
- int Sub(int a, int b)
- {
- return Add(a, negtive(b));
- }
-
-
- int ispos( int a )
- {
- return (a&0xFFFF) && !(a&0x8000);
- }
- int isneg( int a )
- {
- return a&0x8000;
- }
- int iszero( int a )
- {
- return !(a&0xFFFF);
- }
-
-
- int Pos_Multiply(int a,int b)
- {
- int ans = 0;
- while(b)
- {
- if(b&1)
- ans = Add(ans, a);
- a = (a<<1);
- b = (b>>1);
- }
- return ans;
- }
-
-
- int Multiply(int a,int b)
- {
- if( iszero(a) || iszero(b) )
- return 0;
- if( ispos(a) && ispos(b) )
- return Pos_Multiply(a, b);
- if( isneg(a) )
- {
- if( isneg(b) )
- {
- return Pos_Multiply( negtive(a), negtive(b) );
- }
- return negtive( Pos_Multiply( negtive(a), b ) );
- }
- return negtive( Pos_Multiply(a, negtive(b)) );
- }
-
-
- int Pos_Div(int x,int y)
- {
- int ans=0;
- for(int i=31;i>=0;i--)
- {
-
- if((x>>i)>=y)
- {
- ans+=(1<<i);
- x-=(y<<i);
- }
- }
- return ans;
- }
-
-
- int MyDiv( int a, int b )
- {
- if( iszero(b) )
- {
- cout << "Error" << endl;
- exit(1);
- }
- if( iszero(a) )
- return 0;
- if( ispos(a) )
- {
- if( ispos(b) )
- return Pos_Div(a, b);
- return negtive( Pos_Div( a, negtive(b)) );
- }
- if( ispos(b) )
- return negtive( Pos_Div( negtive(a), b ) );
- return Pos_Div( negtive(a), negtive(b) );
- }
-
-
-
- int isbig_pos( int a, int b )
- {
- int c = 1;
- b = (a^b);
- if( iszero(b) )
- return 0;
- while( b >>= 1 )
- {
- c <<= 1;
- }
- return (c&a);
- }
-
-
- int isbig( int a, int b )
- {
- if( isneg(a) )
- {
- if( isneg(b) )
- {
- return isbig_pos( negtive(b), negtive(a) );
- }
- return 0;
- }
- if( isneg(b) )
- return 1;
- return isbig_pos(a, b);
- }
扩展:在不使用*、/、+、-、%操作符的情况下,如何求一个数的1/3?(用C语言实现)
使用位操作符并实现“+”操作
-
- int add(int x , int y)
- {
- int res;
- while(y)
- {
- res = x^y;
- y = ((x&y)<<1);
- x = res;
- }
- return x;
- }
-
- int divideby3(int num)
- {
- int sum = 0;
- while(num > 3)
- {
- sum = add(num>>2 , sum);
- num = add(num>>2 , num&3);
- }
- if(num == 3)
- sum = add(sum , 1);
- return sum;
- }
原理:n = 4 * a + b; n / 3 = a + (a + b) / 3; 然后 sum += a, n = a + b 并迭代; 当 a == 0 (n < 4)时,sum += floor(n / 3); i.e. 1, if n == 3, else 0