C 언어: 비트 연산(bitwise operation)_000027
C언어: 몫
/// 연산
a = b * q + r, (a, b는 정수, q는 몫, r은 나머지)
/// 예제
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 | #include <stdio.h> void show_binary(int value); // decimal to binary // 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 //------------------------------------------------------------------------------- //---------------------- // main() implementation int main(void) { puts("finding quotient!"); puts("-------------------------------------------------------"); puts("in real life,"); puts("10, 100, 1000, ... we are familiar with these numbers."); puts("-------------------------------------------------------"); puts(" x / 3"); puts("= x * 334 / 3 * 334 = x * 334 / 1002"); puts(" ≒ x * 334 / 1000(≒1002)"); puts("-------------------------------------------------------"); puts(" 44 / 3 ≒ 14.666666666 (quotient = 14)"); puts("= 44 * 334 / 3 * 334 = 14966 / 1002"); puts(" ≒ 14966 / 1000(≒1002))"); puts(" = 14.966 (quotient = 14)"); puts("-------------------------------------------------------"); // certain range of x for (register int i = 0; i < 100; i++) { printf("%d/3=%d, %d*334/1000=%d\n", i, i/3, i, i*334/1000); } puts("-------------------------------------------------------"); puts("in computing system, multiplier is faster than divider."); puts("x/2, x/4, x/8, ... we can use shift operation."); puts("-------------------------------------------------------"); // reference: https://www.codeproject.com/Articles/17480/Optimizing-integer-divisions-with-Multiply-Shift-i // Jeffrey Sax's operation puts(" 1500 / 88"); puts("= 1500 * 745 / 88 * 745"); puts("= 1500 * 745 / 65560(≒65536=2^16)"); puts("= 1500 * 745 and shift operation( >> 16)"); puts("-------------------------------------------------------"); printf("case01: 1500 / 88 = %d\n", 1500 / 88); printf("case02: 1500 / 88 = %d\n", r_shift((1500 * 745), 16)); puts("-------------------------------------------------------"); printf("1500 : "); /* << */ show_binary(1500); /* << */ puts(""); printf("745 : "); /* << */ show_binary(745); /* << */ puts(""); printf("1500 * 745 : "); /* << */ show_binary(1500 * 745); /* << */ puts(""); printf("(1500 * 745) >> 16: "); /* << */ show_binary(r_shift((1500 * 745), 16)); /* << */ puts(""); printf("1500 / 88 : "); /* << */ show_binary(1500 / 88); /* << */ puts(""); puts("-------------------------------------------------------"); return 0; } //----------------------------- // show_binary() implementation void show_binary(int value) { const int MAX_BIT = 32; const int INT_MIN = -2147483648; enum flag { OFF = -1, ON = 1 } sign_switch = OFF; // 필요개념에 의해 정의 int mask = INT_MIN; // 10000000 00000000 00000000 00000000 for (register int i = MAX_BIT; i >= 1; i--) { printf("%d", and_gate(value, mask) ? 1 : 0); mask = r_shift(mask, 1); // 1로 right shift하는 것을 방지 if (sign_switch == OFF && i == MAX_BIT) { // 11000000 00000000 00000000 00000000 mask = xor_gate(mask, INT_MIN); // -> 01000000 00000000 00000000 00000000 sign_switch = ON; } if (and_gate((i-1), 7) == 0) printf(" "); // 가독성을 위한 분리자 } // think different! } | cs |
* 실행환경: Linux(5.7.6-x86_64-linode136)
* 컴파일러: gcc (Ubuntu 6.5.0-2ubuntu1~14.04.1) 6.5.0 20181026
- 당신을 응원합니다. -
댓글
댓글 쓰기