Do not use arithmetic operators to implement integer addition, subtraction, multiplication and division operations

Do not use arithmetic operators to implement integer addition, subtraction, multiplication and division operations

Title description:

Given two 32-bit integers a and b. It is required not to use arithmetic operators, and realize the addition, subtraction, multiplication, and division operations of a and b respectively. If some of the results of adding, subtracting, multiplying and dividing given a and b would have caused data overflow, then the function you implement does not need to be responsible for those results (your output is consistent with the result of addition, subtraction, multiplication, and division overflow).

Enter a description:

Enter a line containing two integers a and b (both a and b are 32-bit integers) and an operator. The operator is one of "+", "-", "*", and "". (Data guarantee will not divide by 0)

Output description:

Output an integer, which is the result calculated by the above expression.

Example 1
enter
2 * 4
Output
8
Example 2
enter
5 / 4
Output
1
Example 3
enter
3 + 23
Output
26
Remarks:

Time complexity O (1) O (1)O ( 1 ) , additional space complexityO (1) O(1)O ( 1 )


answer:

The most important point of this question is: addition is realized, and the subsequent subtraction, multiplication and division can all be converted into addition operations.

addition:

  • Do not consider the case of carry: a + b = a ^ b;

  • Only consider the case of carry: a + b = (a&b) << 1;

Adding the result of not considering carry and only considering carry is the final result. That is to repeat the above process until the carry is 0.

Subtraction:

ab = a+(-b), so turn b into one's complement and just add it directly.

multiplication:

a ∗ b = a ∗ 2 0 ∗ b 0 + a ∗ 2 1 ∗ b 1 + a ∗ 2 2 ∗ b 2 + . . . + a ∗ 2 31 ∗ b 31 a*b = {a}*{2^0}*b_0+{a}*{2^1}*b_1+{a}*{2^2}*b_2+...+{a}*{2^{31}}*b_{31} ab=a20b0+a21b1+a22b2+...+a231b31

Calculate directly according to this law. Note: b may be a negative number and needs to be dealt with.

division:

The inverse operation of multiplication is enumerated from the highest order. If (a >> i) >= b, then a -= (b << i) and record the result. Need special treatment element 1<<31:

  • If both a and b are not the minimum, just calculate directly;

  • If both a and b are the minimum, just return 1 directly;

  • If a is not the minimum value and b is the minimum value, return 0;

  • If a is the minimum value and b is not the minimum value, special treatment is required:

    • Assuming a=-10, b=5, that is, the maximum value is 9 and the minimum value is -10;
    • Calculate (a+1)/b and mark it as c;
    • Calculate c*b and mark it as d;
    • Calculate ad and mark it as e;
    • Calculate e/b and record it as ret;
    • Return ret+c.

    In other words, it is a bit difficult to calculate directly, so we can increase the minimum value a bit and then modify it.

Code:
#include <cstdio>
using namespace std;
const int MIN = 1 << 31;

int add( int a, int b ) {
    
    
    int ret = a;
    while ( b ) {
    
    
        ret = a ^ b;
        b = ( a & b ) << 1;
        a = ret;
    }
    return ret;
}

int negNum( int n ) {
    
    
    return add( ~n, 1 );
}

int minus( int a, int b ) {
    
    
    return add( a, negNum( b ) );
}

inline bool isNeg( int n ) {
    
    
    return n < 0;
}

int multi( int a, int b ) {
    
    
    int ret = 0;
    int x = isNeg( a ) ? negNum( a ) : a;
    int y = isNeg( b ) ? negNum( b ) : b;
    while ( y ) {
    
    
        if ( y & 1) ret = add( ret, x );
        y >>= 1;
        x <<= 1;
    }
    return isNeg( a ) ^ isNeg( b ) ? negNum( ret ) : ret;
}

int div( int a, int b ) {
    
    
    int x = isNeg( a ) ? negNum( a ) : a;
    int y = isNeg( b ) ? negNum( b ) : b;
    int ret = 0;
    for ( int i = 31; i > -1; i = minus( i, 1 ) ) {
    
    
        if ( ( x >> i ) >= y ) {
    
    
            ret |= ( 1 << i );
            x = minus( x, y << i );
        }
    }
    return isNeg( a ) ^ isNeg( b ) ? negNum( ret ) : ret;
}

int divide( int a, int b ) {
    
    
    if ( a == MIN && b == MIN ) return 1;
    else if ( b == MIN ) return 0;
    else if ( a == MIN ) {
    
    
        int ret = div( add( a, 1 ), b );
        return add( ret, div( minus( a, multi( ret, b ) ), b ) );
    } else return div( a, b );
}

int main(void) {
    
    
    int a, b;
    char op;
    scanf("%d %c %d", &a, &op, &b);
    int ret;
    if ( op == '+' ) ret = add( a, b );
    else if ( op == '-' ) ret = minus( a, b );
    else if ( op == '*' ) ret = multi( a, b );
    else ret = divide( a, b );
    return 0 * printf("%d\n", ret);
}

Guess you like

Origin blog.csdn.net/MIC10086/article/details/109100002