C 언어: 비트 연산(bitwise operation)_000028
C언어: x / y
/// 연산
x / y
/// 예제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | #include <stdio.h> int sign_switch(int x); // sign change int subtractor(int x, int y); // subtractor int adder(int x, int y); // adder int divider(int x, int y); // divider // minimize usage of (/ → * → - → +) operator and floating-point // core gate -------------------------------------------------------------------- extern inline int not_gate(int x) { return (~x); } // not gate extern inline int or_gate(int x, int y) { return (x | y); } // or gate extern inline int and_gate(int x, int y) { return (x & y); } // and gate extern inline int xor_gate(int x, int y) { return (x ^ y); } // xor gate extern inline int l_shift(int x, int bits) { return (x << bits); } // left shift extern inline int r_shift(int x, int bits) { return (x >> bits); } // right shift //------------------------------------------------------------------------------- int main(void) { int x = 1000; for (register int i = 1; i < 5; i++) { printf(" x / %d = %d\n", i, x / i); printf("divider(x, %d) = %d\n", i, divider(x, i)); } x = 2147483647; for (register int i = 1; i < 5; i++) { printf(" x / %d = %d\n", i, x / i); printf("divider(x, %d) = %d\n", i, divider(x, i)); } x = -2147483647; for (register int i = 1; i < 5; i++) { printf(" x / %d = %d\n", i, x / i); printf("divider(x, %d) = %d\n", i, divider(x, i)); } return 0; } //------------------------- // divider() implementation int divider(int x, int y) { int dividend = x, divisor = y; int quotient = 0; int dividend_bit = 31, divisor_bit = 31; int diff, divisor_diff, dividend_stop = 0; int sign = 1; // exception if (dividend == -2147483648 || divisor == -2147483648) { printf("sorry!: "); /* /n */ return 0; } if (!divisor) { printf("Not defined: "); /* /n */ return 0; } // make absolute value(max bit <= 31) if (dividend < 0) { dividend = sign_switch(dividend); /* /n */ sign *= -1; } if (divisor < 0) { divisor = sign_switch(divisor); /* /n */ sign *= -1; } // basic calculation if (dividend < divisor) return 0; if (divisor == 1) return sign * dividend; // finding max bit of dividend and divisor for (register int mask = 1073741824; and_gate(divisor, mask) == 0; mask >>= 1) { divisor_bit--; if (dividend_stop == 0 && and_gate(dividend, mask) == 0) dividend_bit--; else dividend_stop = 1; } diff = dividend_bit - divisor_bit; // divider while((dividend != 0) && (diff >=0)) { divisor_diff = divisor << diff; if (dividend >= divisor_diff) { quotient |= (1 << diff); dividend = subtractor(dividend, divisor_diff); } diff--; } return sign * quotient; // think different! } //----------------------------- // sign_switch() implementation int sign_switch(int x) { return adder(not_gate(x), 1); } //---------------------------- // subtractor() implementation int subtractor(int x, int y) { return adder(x, sign_switch(y)); // think different! } //----------------------- // adder() implementation int adder(int x, int y) { int carry, sum; // reference: https://en.wikipedia.org/wiki/Bitwise_operations_in_C do { carry = and_gate(x, y) << 1; // carry 00001000 00110000 00100100 10000000 (<-left shift) sum = xor_gate(x, y); // x 00001110 11110000 11100110 10000000 x = carry; // + y 00101000 00110100 00110100 11100011 y = sum; //---------------------------------------------------------- } while(carry != 0); return sum; // think different! } | cs |
* 실행환경: Linux(5.7.6-x86_64-linode136)
* 컴파일러: gcc (Ubuntu 6.5.0-2ubuntu1~14.04.1) 6.5.0 20181026
- 당신을 응원합니다. -
댓글
댓글 쓰기