Data structure - only use bit operations to implement addition, subtraction, multiplication and division operations

implement addition

https://www.jianshu.com/p/7bba031b11e7

https://blog.csdn.net/ojshilu/article/details/11179911

public class Arithmetic {
    /**
     * The sum of two numbers
     * XOR operation (^) results in sum
     * AND operation (&) results in a carry
     * Continue to add sum and carry<<1
     * @param a
     * @param b
     * @return
     */
    public static int add(int a, int b){
        if(b == 0) return a;
        int sum = a ^ b;
        int carry = (a & b) << 1;
        return add(sum, carry);
    }

    /**
     * The difference between two numbers
     * a - b is actually a + (-b)
     * When doing subtraction in practice, -b is negated with complement + 1
     * @param a
     * @param b
     * @return
     */
    public static int substract(int a, int b){
        return add(a, negative(b));
    }

    /**
     * Find the inverse of a number and then +1
     * @param a
     * @return
     */
    public static int negative(int a){
        return add(~a, 1);
    }


    /**
     * Find the sign of a number,
     * 0 is a positive number, otherwise it returns -1
     * @param a
     * @return
     */
    public static int sign(int a){
        return a >> 31;
    }

    /**
     * Make the number positive, if the number is positive, it is itself, if it is negative, it becomes its opposite
     * @param a
     * @return
     */
    public static int positive(int a){
        int flag = sign( a );

        if(flag == 0) return a;
        else return negative( a );
    }

    /**
     * Product of two numbers
     * Calculate the product of two positive numbers first, then add the sign at the end
     * The product of two positive numbers, a, b is the addition of a for b times
     * Note the symbol at the end
     * @param a
     * @param b
     * @return
     */
    public static int multiply(int a, int b){
        boolean flag = sign(a) != sign(b);
        a = positive( a );
        b = positive( b );
        int res = 0;
        while(b > 0){
            res = add(res, a);
            b = substract( b, 1 );
        }
        if(flag){
            return negative( res );
        }
        return res;
    }

    /**
     * Product of two numbers
     * 0101
     * 0110
     *
     *    0000
     *   0101
     *  0101
     * 0000
     * The corresponding position can be summed
     *
     * If each bit of b is 1, just shift a left by one bit and add it to res, if it is 0, do nothing
     * @param a
     * @param b
     * @return
     */
    public static int multiplay1(int a, int b){
        boolean flag = (sign(a) != sign(b));
        a = positive( a );
        b = positive( b );

        int res = 0;
        while(b > 0){
            if((b & 1) == 1){
                res = add(res, a);
            }
            a = a << 1;
            b = b >> 1;
        }

        if(flag) return negative( res );
        return res;

    }


    /**
     * Quotient of two numbers
     * Use a - b, keep subtracting, until a < b, the number of times of subtraction is the quotient, and a is the remainder
     * Note that there are symbols
     * @param a
     * @param b
     * @return
     */
    public static int divide(int a, int b){
        if(b == 0) return -1;
        boolean flag = (sign(a) != sign(b));
        int res = 0;
        a = positive( a );
        b = positive( b );
        while(a >= b){
            res = add(res, 1);
            a = substract( a, b );
        }
        if(flag){
            return negative( res );
        }
        return res;
    }


    /**
     * Quotient of two numbers
     * The above method subtracts a b each time. If b is too small, the calculation will be very slow
     * And if you start subtracting 2^i times b, if a is enough to subtract, add 2^i times to the result
     * First, judge whether a is greater than 2^i times of b
     * Change to judge the size of a / (2 ^ i) and b, which can prevent overflow
     *  a * (1 >> i) = a >> i
     *  (a >> i) >= b
     * @param a
     * @param b
     * @return
     */
    public static int divide1(int a, int b){
        if(b == 0) return -1;

        boolean flag = (sign( a ) != sign( b ));
        a = positive( a );
        b = positive( b );

        int res = 0;
        int i = 31;
        while(i >= 0){
            if((a >> i) >= b){
                res = add( res, 1 << i );
                a = substract( a, b << i );
            }
            i = substract( i, 1 );
        }
        if(flag) return negative( res );
        return res;
    }


    public static void main(String[] args){
        System.out.println(add( 7, 5 ));
        System.out.println(substract( 7, 5 ));
        System.out.println(negative(-33));
        System.out.println(sign( -23 ));
        System.out.println(positive( 3 ));
        System.out.println(multiply( -7, -5 ));
        System.out.println(divide( -35, -5 ));
        System.out.println(divide1( -35, -5 ));

        System.out.println(multiplay1( -7, 5 ));
    }
}

  

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325985081&siteId=291194637