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== 0printf(" "); // 가독성을 위한 분리자
    }
    // 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 - 한글 사용

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

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