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


- 당신을 응원합니다. -

댓글

이 블로그의 인기 게시물

파이썬[Python]: 내장함수 - from_bytes 메서드

파이썬[Python]: 내장함수 - __len__ 메서드

파이썬[Python]: kivy - 한글 사용

파이썬[Python]: 내장함수 - bit_length 메서드

C 언어: sin 함수, cos 함수, tan 함수