Java-bit computing to achieve four arithmetic operations

This article is the second "article for an interesting bit computing," the second article.

We know that the basic operation of the computer unit is a byte (byte), a byte consists of 8 bits (bit) composition, can only store a bit 1 or a 0, that is, in fact, high and low. No matter how complex logic, large data, cool interface, ultimately reflected in the bottom of the computer are only for 0101 of storage and computing. Therefore, understanding bit computing help to improve our understanding of the underlying principles of operation of the computer.

First, the addition

Two binary XOR operation result is reached without considering the carry bit,

Two binary AND operation result is contained in the bit 1 is the carry bit.

With 0101 + 0001 = 0110an example as follows:

//计算 0101 + 0001
0101 ^ 0001 = 0100 //异或结果表明,如果不考虑进位,那么结果为0100
0101 & 0001 = 0001 //与运算结果表明,最低位需要向次低位进1
0001 << 1 = 0010   //与运算结果左移一位,将进位加到高位上

//递归计算 0100 + 0010,直到+号右侧数字为0

java code:

Recursion


public static int add(int a, int b) {
   if (b == 0) {
       return a;
   } else {
       return add(a ^ b, (a & b) << 1);
   }
}

cycle


public static int add2(int a, int b) {
    int sum = a;
    while (b != 0) {
        sum = a ^ b;
        b = (a & b) << 1;
        a = sum;
    }
    return sum;
}

Second, subtraction

The same ideas and additions, but minus a number plus a number equal to the number of the opposite.

For example: 5 + 5-1 = (- 1). So, we simply requires the opposite number to the minuend.

How to find a number of opposite number?

Is stored in the computer's complement form, with positive complement of the same original code, complement negative number in addition to the original code symbol bits Members inverted, and then the last one by one.

E.g:

1 in the computer's binary represented as: 0000 0001

-1 binary represented in the computer as: 11,111,111

The calculation is:

-1 original code: 10000001

Inverted -1: 1111 1110

Complement -1: 1111 1111

Wherein 1 is the original code (0000 0001) can be inverted to obtain the inverted-1 (11111110)

Summary, a number of opposite number is the number of the method for finding every negated, the last one plus one.

java code:

public static int minus(int a, int b) {
    return add(a, add(~b, 1));
}

Third, multiplication

Without thinking, you can multiply the binary process on paper written calculation:

        0101    a
    ×   0110    b
    ----------------
        0000    
       0101   
      0101      
   + 0000       
    ----------------
     00011110

Carding written calculation binary multiplication under:

Initialize multiplication result is 0, the last bit, traversing a digital b 0 → 1 → 1 → 0, when the last bit is 0, the multiplication results together with 0, i.e. the same product, A a left; when the last bit of 1, the multiplication results together with A, A and then the left one.

How to traverse the last bit digital b it?

The learned earlier, we can take a number of operational last bit, and B numbers shifted right, until the number b == 0, to the end of the displacement.

Note that the number of positive and negative sign problem here is to calculate the product of the absolute value of a, b of the two numbers, and finally their sign.

java code:

public static int multiply(int a, int b) {
      //将乘数和被乘数都取绝对值
      int A = a < 0 ? add(~a, 1) : a;
      int B = b < 0 ? add(~b, 1) : b;
      //计算绝对值的乘积
      int P = 0;
      while (B != 0) {
          if ((B & 1) != 0) { //取乘数的二进制的最后一位,0 or 1
              P = add(P, A);
          }
          A = A << 1;
          B = B >> 1;
      }
      //计算乘积的符号
      if ((a ^ b) < 0) {
          P = add(~P, 1);
      }
      return P;
}

Fourth, the division

The easiest division to achieve is to keep the divisor used to cut the dividend, until the dividend is less than the divisor, the number at this time is that we need to reduce business, but this time the dividend is remainder.

The only caveat is the symbol and sign of the remainder providers. Symbol's also determine the way multiplication is the same, that is, the same number is positive, negative opposite sign. The signs and symbols of the remainder of the dividend is the same.

And simple multiplication realized, as here, we must first of the absolute value of the quotient of two numbers, find the remainder. Finally, determine the symbol.

public static int[] divide(int a, int b) {
      //对被除数和除数取绝对值
      int A = a < 0 ? add(~a, 1) : a;
      int B = b < 0 ? add(~b, 1) : b;
      //对被除数和除数的绝对值求商
      int C = A; // 余数C
      int N = 0; // 商N
      while (C >= B) {
          C = minus(C, B); // C-B
          N = add(N, 1); // N+1
      }
      // 求商的符号
      if ((a ^ b) < 0) {
          N = add(~N, 1);
      }
      // 求余数的符合
      if (a < 0) {
          C = add(~C, 1);
      }
      return new int[]{N, C};
}

It should be noted that this algorithm in a big A, B minor cases inefficient, how that the optimization algorithm to reduce the number of the while loop it?

Not difficult to think, the process of multiplication by division Backward come. E.g. 9 ÷ 4 = 2 ... 1, which is 2 * 4 + 1 = 9. Suppose that 4 * Save 2 to 9, the outcome may be equal to 1, because 1 is less than 4, it can be obtained commercially 9 ÷ 4 is 2, the remainder is 1.

How to determine the multiple of 4 is the key to approaching the final result. We know, int 32-bit integer, in addition to showing the first sign bit, the size of each bit of [2 ^ 0, 2 ^ 1, 2 ^ 2, 2 ^ 30], the maximum is an integer of 2 ^ int 31 -1. Therefore, we can turn to the dividend 2 ^ 31, 2 ^ 30, 2 ^ 3 ..., 2 ^ 2, 2 ^ 1, multiplied by 1, if their product is greater than the divisor, the divisor will therewith subtraction, and with the remainder obtained by subtracting continue to serve as the divisor until the end of the loop.

java code:

public static int[] divide(int a, int b) {
    // 对被除数和除数取绝对值
    int A = a < 0 ? add(~a, 1) : a;
    int B = b < 0 ? add(~b, 1) : b;

    int N = 0; // 商 N
    for (int i = 31; i >= 0; i--) {
        // 未使用A>=(B<<i)进行判断,因为只有左移B时舍弃的高位不包含1,才相当于该数乘以2的i次方.
        if ((A >> i) >= B) { // A ÷ 2^i >= B
            N += (1 << i); // N = N + 2^i
            A -= (B << i); // A = A - B*2^i
        }
    }

    int C = A; // 余数C
    // 求商的符号
    if ((a ^ b) < 0) {
        N = add(~N, 1);
    }
    // 求余数的符号
    if (a < 0) {
        C = add(~C, 1);
    }
    return new int[]{N, C};
}

Guess you like

Origin www.cnblogs.com/yueshutong/p/11481724.html