๋ถ์กฑํ ๋ถ๋ถ์ด ๋ง์ ์ฝ๋๊ฐ ๊ทธ๋ฆฌ ๊น๋ํ์ง๋ ์์ต๋๋ค.. ใ
(์ํ ๋ค๋ค ํ์ดํ ํ์ธ์๐)
๐ง addOK
/*
* addOK - Determine if can compute x+y without overflow
* Example: addOK(0x80000000,0x80000000) = 0,
* addOK(0x80000000,0x70000000) = 1,
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 20
* Rating: 3
*/
int addOK(int x, int y) {
/*
* Overflow๊ฐ ๋ฐ์ํ๋ ๊ฒฝ์ฐ๋ ๋ค์๊ณผ ๊ฐ๋ค.
* (1) MSB_X = 0, MSB_Y = 0, MSB_(X+Y) = 1
* (2) MSB_X = 1, MSB_Y = 1, MSB_(X+Y) = 0
*
* ๋ฐ๋ผ์
* MSB_X [XOR] MSB_Y ์ ๊ฒฐ๊ณผ๊ฐ 0์ด๊ณ ,
* MSB_(X+Y) [XOR] MSB_X ์ ๊ฒฐ๊ณผ๊ฐ 1์ธ ๊ฒฝ์ฐ
* Overflow ๊ฐ ๋ฐ์๋ ๊ฒฝ์ฐ์
๋๋ค.
*/
int xMSB = x>>31;
int yMSB = y>>31;
int xyMSB = (x+y)>>31;
return !((~(xMSB ^ yMSB) & (xyMSB ^ xMSB)));
}
์ฒ์์๋ ์บ๋ฆฌ๋นํธ๋ฅผ ํตํ ์ค๋ฒํ๋ก์ฐ ๊ฒ์ถ์ ํ๋ ค ์๋ํ์ต๋๋ค.
๊ทธ๋ฌ๋ ์บ๋ฆฌ๋นํธ์ ๊ฒ์ถ์ด ์๊ฐ๋ณด๋ค ์ด๋ ค์ ๊ธฐ์ ํฌ๊ธฐํ ํ, ๋ค์๊ณผ ๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก ๊ตฌํ์ต๋๋ค.
์ฐ์ ๋ง์ ์์ Overflow๊ฐ ๋ฐ์ํ๋ ๊ฒฝ์ฐ๋ ๋ค์ ๋ ๊ฒฝ์ฐ์ ๋๋ค.
x์ MSB(๋๋ ๋ถํธ๋นํธ) | y์ MSB | x+y์ MSB | |
case 1 | 1 | 1 | 0 |
case 2 | 0 | 0 | 1 |
์ ๋๊ฐ์ง ๊ฒฝ์ฐ์๋ง 0์ ๋ฐํํ๋๋ก ๋ ผ๋ฆฌ์์ ์์ฑํ์์ต๋๋ค.
$x$ ์ $y$, $x+y$ ์ ๋ถํธ๋นํธ๋ฅผ ๊ฐ๊ฐ $x_s, \;y_s, \;(x+y)_{s}$ ๋ผ ํ๊ฒ ์ต๋๋ค.
์ฒ์์ผ๋ก๋ $x$ ์ $y$ ์ ๋ถํธ๋นํธ๋ฅผ ํตํด ์ค๋ฒํ๋ก์ฐ ๊ฐ๋ฅ์ฑ์ด ์๋ ๊ฒฝ์ฐ 1์ ๋ฐํํ๋๋ก ์์ ์์ฑํ์ต๋๋ค.
$(x_{s} $ ⊕ $y_{s})$ ๋ ์ ๋๊ฐ์ง ๊ฒฝ์ฐ 0์ ๋ฐํํฉ๋๋ค. (⊕๋ XOR ์ฐ์ฐ์ ์๋ฏธํฉ๋๋ค.)
๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ 0์ด ์๋ ๊ฐ์ ๋ฐํํฉ๋๋ค. (์ฝ๋์์ผ๋ก๋ 0xFFFFFFFF ์ ๋ฐํํฉ๋๋ค.)
ํด๋น ๊ฐ์ ~์ฐ์ฐ(NOT)์ ์ฌ์ฉํ์ฌ,
0์ธ ๊ฒฝ์ฐ(false) -> 0์ด ์๋ ๊ฐ(false),
0์ด ์๋ ๊ฒฝ์ฐ(true) -> 0(true)์ผ๋ก ๋ฐ๊พธ์ด์ค๋๋ค.
์ฆ Overflow๊ฐ ๋ฐ์ํ ์ ์๋ ์กฐ๊ฑด์ด๋ผ๋ฉด 0์ด ์๋ ๊ฐ์, ๊ทธ๋ ์ง ์๋ค๋ฉด 0์ ๋ฐํํฉ๋๋ค.
๋๋ฒ์งธ๋ก๋ $x+y$ ์ ๋ถํธ๋นํธ์, $x$ ์ ๋ถํธ๋นํธ๋ฅผ ํตํด ์ค๋ฒํ๋ก์ฐ ๊ฐ๋ฅ์ฑ์ ์ฒดํฌํ์ต๋๋ค.
๋ง์ฝ ๋ ๋ถํธ๋นํธ๊ฐ ๋ค๋ฅธ ๊ฒฝ์ฐ ์ค๋ฒํ๋ก์ฐ๊ฐ ๋ฐ์ํ ์ ์์ผ๋ฉฐ,
ํด๋น ๊ฒฝ์ฐ 1์ ๋ฐํํ๋๋ก ์๋ ์์ ์์ฑํ์์ต๋๋ค.
$(x+y)_s$ ⊕ $x_s$
Overflow๊ฐ ๋ฐ์ํ ์ ์๋ ์กฐ๊ฑด์ด๋ผ๋ฉด 0์ด ์๋ ๊ฐ์, ๊ทธ๋ ์ง ์๋ค๋ฉด 0์ ๋ฐํํฉ๋๋ค.
Overflow๊ฐ ๋ฐ์ํ ์ํฉ์ด๋ผ๋ฉด ์ ๋ ๋ ผ๋ฆฌ์์ AND ์ฐ์ฐ์ ๊ฒฐ๊ณผ๊ฐ 0์ด ์๋์ด์ผ ํฉ๋๋ค.
๊ทธ๋ฌ๋ Overflow๊ฐ ๋ฐ์ํ๋ฉด ๋ ผ๋ฆฌ์์ ๊ฒฐ๊ณผ๋ 0์ด์ด์ผ ํ๋ฏ๋ก,
AND ์ฐ์ฐ์ ๊ฒฐ๊ณผ์ ! ์ฐ์ฐ์ ์ทจํด์ค์ผ๋ก์จ, ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์ต๋๋ค.
(์ถ๊ฐ์ ์ผ๋ก $x >> 31$ ์ $x$๊ฐ ์์์ธ ๊ฒฝ์ฐ 0x00000000, x๊ฐ ์์์ธ ๊ฒฝ์ฐ 0xFFFFFFFF ๋ฅผ ๋ฐํํฉ๋๋ค.
์ด๋ x๊ฐ unsigned ํ์ ์ด ์๋ signed int ์ด๋ฏ๋ก, ๋ถํธ๋นํธ๊ฐ 1์ธ ๊ฒฝ์ฐ >> ์ฐ์ฐ์ ์ํํ๋ฉด MSB๊ฐ 1๋ก ์ฑ์์ง๊ธฐ ๋๋ฌธ์ ๋๋ค.)
๐ง allOddBits
/*
* allOddBits - return 1 if all odd-numbered bits in word set to 1
* Examples allOddBits(0xFFFFFFFD) = 0, allOddBits(0xAAAAAAAA) = 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 12
* Rating: 2
*/
int allOddBits(int x) {
/*
* 0xAA = 10101010
* ๋ง์ฝ x์ ๋ชจ๋ ํ์ ๋นํธ๊ฐ 1์ธ ๊ฒฝ์ฐ
* x & 0xAAAAAAAA ์ ๊ฒฐ๊ณผ(1)๋ 0xAAAAAAAA ์
๋๋ค.
*
* ๋ง์ฝ A == B ๋ผ๋ฉด, A ^ B ์ ๊ฒฐ๊ณผ๋ 0 ์ด๋ฏ๋ก,
*
* ์ ๊ฒฐ๊ณผ(1) ๊ณผ 0xAAAAAAAA ์ ^ ์ฐ์ฐ์ ๊ฒฐ๊ณผ๋ 0 ๋๋ 0์ด ์๋ ์ ์ด๋ฏ๋ก,
* ! ์ฐ์ฐ์ ํตํด ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํด์ค๋๋ค.
*/
int evenMask = 0xaa;
evenMask = (evenMask << 8) | evenMask;
evenMask = (evenMask << 16) | evenMask;
return !((x & evenMask) ^ evenMask);
}
์ฐ์ ํ์ ์๋ฆฌ ์๊ฐ ๋ฌด์์ธ์ง ์๊ธฐ ์ํด, ์๋ ์ด์ง์์์ ํ์ ์๋ฆฌ ์๋ฅผ ์ฃผํฉ์์ผ๋ก ํ์ํ๊ฒ ์ต๋๋ค.
$1_7$ $0_6$ $1_5$ $0_4$ $1_3$ $0_2$ $1_1$ $0_0$
ํ์ด๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
1010 1010 [1010]... ๊ณผ x๋ฅผ AND ์ฐ์ฐ ์์ผ์ฃผ๋ฉด ํ์ ๋ฒ์งธ ๋นํธ๋ง ๋จ๊ฒ๋ฉ๋๋ค.
์ด์ ํด๋น ์ฐ์ฐ์ ๊ฒฐ๊ณผ์ ๋ค์ 1010 1010 [1010] .. ์ XOR ์ฐ์ฐ์์ผ์ค๋ค๋ฉด ๋ค์ ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์ต๋๋ค.
ํ์ ์๋ฆฌ ์๊ฐ ๋ชจ๋ 1์ธ ๊ฒฝ์ฐ ๊ฒฐ๊ณผ๋ 0
๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ ๊ฒฐ๊ณผ๋ 0์ด ์๋ ์ด๋ค ์
์ด๋ ๋ชจ๋ ํ์์ธ ๊ฒฝ์ฐ 1, ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ 0์ ๋ฐํํด์ผ ํ๋ฏ๋ก, ! ์ฐ์ฐ์ ํตํด ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋๋ก ๊ตฌํํ์์ต๋๋ค.
๐ง bitNor
/*
* bitNor - ~(x|y) using only ~ and &
* Example: bitNor(0x6, 0x5) = 0xFFFFFFF8
* Legal ops: ~ &
* Max ops: 8
* Rating: 1
*/
int bitNor(int x, int y) {
/*
* -๋ฅผ ์ฌ์ฉํ ์ ์์ผ๋ฏ๋ก ๋๋ชจ๋ฅด๊ฐ์ ๋ฒ์น์ ์ฌ์ฉํฉ๋๋ค.
* (A) OR (B) ๋ ((A)' AND (B)')' ์
๋๋ค.
*
* ๋ฐ๋ผ์
* (A) NOR (B) ๋ (A)' AND (B)'
*/
return ~x & ~y;
}
๋๋ชจ๋ฅด๊ฐ ๋ฒ์น์ ์ฐ๋ฉด ์ฝ๊ฒ ํ๋ฆฌ๋ ๋ฌธ์ ์ ๋๋ค.
์ฃผ์์ ์ฐธ๊ณ ํด์ฃผ์ธ์ฉ :D
๐ง float_neg
/*
* float_neg - Return bit-level equivalent of expression -f for
* floating point argument f.
* Both the argument and result are passed as unsigned int's, but
* they are to be interpreted as the bit-level representations of
* single-precision floating point values.
* When argument is NaN, return argument.
* Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
* Max ops: 10
* Rating: 2
*/
unsigned float_neg(unsigned uf) {
/*
* ๋ถ๋์์์ ํํ์์ ์์์ ์์๋ ๋ถํธ๋นํธ(MSB)๋ง์ด ์ฐจ์ด๋ฉ๋๋ค.
*
* ๋ฐ๋ผ์ uf์ ์์๊ฐ์ 0x80000000 ๊ณผ uf๋ฅผ XOR ํ ๊ฐ์
๋๋ค.
*
*
* (+ infinity <-> - infinity) ๋ฐ๋ผ์ ๋ฌดํ๋๋ ๊ณ ๋ คํ์ง ์์ต๋๋ค.
* (+ 0 <-> - 0) ๋ฐ๋ผ์ 0์ ๊ฒฝ์ฐ๋ ๊ณ ๋ คํ์ง ์์ต๋๋ค.
*
* ๋ง์ฝ NaN ์ธ ๊ฒฝ์ฐ, uf๋ฅผ ๊ทธ๋๋ก ๋ฆฌํดํด์ผ ํฉ๋๋ค.
*
* NaN ์ ์๋์ ๊ฐ์ด ํ๋จํ ์ ์์ต๋๋ค.
* uf์ ๋นํธ๋ฅผ ๋ถํธ๋นํธ, exp, frac ์ธ ๋ถ๋ถ์ผ๋ก ๋๋๋ฉด, ๋นํธ ๊ธธ์ด๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. [1][8][23],
* (1) exp ์ฆ [8] ์ด 0xff ์ธ ๊ฒฝ์ฐ
* (2) frac ์ฆ [23] ์ด 0๋ณด๋ค ํฐ ๊ฒฝ์ฐ
* (1) ๊ณผ (2) ๋ฅผ ๋ชจ๋ ๋ง์กฑํด์ผ๋ง uf๊ฐ NaN ์
๋๋ค.
*
* exp ๋ ์๋์ ๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก ์ป์ ์ ์์ต๋๋ค.
* uf & 0 1111 1111 0000 0000 ....
* ์ฆ uf & (ff << 23)
*
* frac ์ ์๋์ ๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก ์ป์ ์ ์์ต๋๋ค.
* uf << 9 ์ ๊ฐ์ [23]0000..0 ์
๋๋ค.
* ๋ฐ๋ผ์ (uf << 9) >> 9 ์ ๊ฐ์ [23] ์ด๋ฉฐ, ๊ทธ๊ฒ์ด frac ์
๋๋ค.
*
* ! ๊ทธ๋ฌ๋ NaN์ ๊ฒฝ์ฐ, frac์ 0์ด ์๋๋๋ค. !
*
* ๋ฐ๋ผ์ frac ์ด 0์ธ ๊ฒฝ์ฐ, [23]0000..00 ์ญ์ 0์
๋๋ค.
* ์ฆ ์ฐ๋ฆฌ๋ frac์ ์ ํํ ๊ฐ์ ๊ตฌํ๊ธฐ ์ํด >> 9 ์ฐ์ฐ์ ํด์ฃผ์ง ์์๋ ๋ฉ๋๋ค. (์ฐ์ฐ์ ์ ์ค์ด๊ธฐ)
*/
//๋น์ ๊ทํ ์ฒดํฌํ๊ธฐ์๋ง Mask : 0 [1111 1111] 0000 0000 ...
unsigned deserializeMask = (0xff << 23);
unsigned exp = (uf & deserializeMask);
unsigned frac = (uf << 9);
// ๋ถํธ ๋ฐ์ ์ ์ํด XOR์ ํด์ค Mask: 1000 0000 0000 ...
unsigned mask = 0x80 << 24;
// NaN ํ๋จ : exp๊ฐ 1111 1111 ์ด๋ฉฐ, frac์ด 0 ์ด์์ธ ๊ฒฝ์ฐ
if ((exp == deserializeMask) && frac) return uf;
// ๋ถํธ๊ฐ ๋ฐ์ ํ์ฌ ๋ฆฌํด
return uf ^ mask;
}
๐ง float_twice
/*
* float_twice - Return bit-level equivalent of expression 2*f for
* floating point argument f.
* Both the argument and result are passed as unsigned int's, but
* they are to be interpreted as the bit-level representation of
* single-precision floating point values.
* When argument is NaN, return argument
* Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
* Max ops: 30
* Rating: 4
*/
unsigned float_twice(unsigned uf) {
/*
*
* ๋ง์ฝ exp ๊ฐ 0x00 ์ธ ๊ฒฝ์ฐ
* -> 2๋ฅผ ๊ณฑํ ๊ฐ์ ๋ฐํํด์ผ ํ๋๋ฐ, ์ด๋ ๋ถํธ๋ ์ ์งํด์ผ ํจ.
*
* ๋ง์ฝ exp ๊ฐ 0xff ์ธ ๊ฒฝ์ฐ + frac์ด 0์ด ์๋ ๊ฒฝ์ฐ
* -> NaN ์ด๋ฏ๋ก ๊ทธ๋๋ก ๋ฐํ
*
* ๋๋จธ์ง์ ๊ฒฝ์ฐ exp์ 1์ ๋ํด์ฃผ๋ฉด ๋๋ค.
*/
unsigned MSB = (uf >> 31)<<31;
unsigned deserializeMask = (0xff << 23);
unsigned exp = (uf & deserializeMask);
// 00์ธ ๊ฒฝ์ฐ ๋น์ ๊ทํ -> ์ผ์ชฝ์ผ๋ก 1์นธ Shift(X2) + ๋ถํธ๋นํธ
if (exp == 0x00) return (uf << 1) + (MSB);
// NaN์ด๊ฑฐ๋ ๋ฌดํ๋์ธ ๊ฒฝ์ฐ (exp ๊ฐ 1111 1111 ์ธ ๊ฒฝ์ฐ)-> ๊ฐ ๊ทธ๋๋ก ๋ฐํ
if (exp == deserializeMask) return uf;
// ์ ๊ทํ์ธ ๊ฒฝ์ฐ exp + 1
return uf + (0x01 << 23);
}
๐ง rempwr2
/*
* rempwr2 - Compute x%(2^n), for 0 <= n <= 30
* Negative arguments should yield negative remainders
* Examples: rempwr2(15,2) = 3, rempwr2(-35,3) = -3
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 20
* Rating: 3
*/
int rempwr2(int x, int n) {
int remainderMask = (1 << n) + ~0; // 000[1]000 + 1111111 = 000[0]111
int remainder = x & remainderMask; // ๋๋จธ์ง
/*
* remainderIsZeroThen0Else1 : remind๊ฐ 0์ด๋ฉด 0, ์๋๋ฉด 1
* remainder๋ 1์ด ์๋ ์๋ ์์ผ๋ฏ๋ก [!!]์ ํตํด 0 ๋๋ 1์ ๊ฐ๋ง ๊ฐ๋๋ก ํ์์
*/
int remainderIsZeroThen0Else1 = !!remainder;
/*
* remainderIsZeroThen0Else1 ๊ฐ 1์ผ ๊ฒฝ์ฐ -> 2^n์น
* (= ๋๋จธ์ง๊ฐ 0์ด ์๋ ๊ฒฝ์ฐ)
*
* remainderIsZeroThen0Else1 ๊ฐ 0์ผ ๊ฒฝ์ฐ -> 0
* (= ๋๋จธ์ง๊ฐ 0์ธ ๊ฒฝ์ฐ)
*/
int twoPowerN = remainderIsZeroThen0Else1 << n;
/*
* -A = ~A(2์ ๋ณด์) + 1
* -2^n = ~2^n + 1
*
* 0์ธ ๊ฒฝ์ฐ ๊ทธ๋๋ก 0์ด๋ค.
*/
int negative2PowerN = ~twoPowerN + 1;
/*
* ๋๋จธ์ง ๊ฐ์ด ์์์ธ ๊ฒฝ์ฐ ์ฒ๋ฆฌํด์ฃผ๊ธฐ ์ํด ์ฌ์ฉํ๋ค
*
* x๊ฐ ์์์ธ ๊ฒฝ์ฐ : 0xFFFFFFFF
* x๊ฐ ์์์ธ ๊ฒฝ์ฐ : 0x00000000
*/
int MSBMask = x >> 31; // 11...11 or 00..00
/**
* 1. [x]๊ฐ ์์์ธ ๊ฒฝ์ฐ.
* -> MSBMask๊ฐ 0์ด๋ฏ๋ก, &์ฐ์ฐ์ ๊ฒฐ๊ณผ๋ ํญ์ 0, ๋ฐ๋ผ์ ๋ํด๋ ๊ฒฐ๊ณผ์ ์ง์ฅ์ด ์๋ค.
*
* 2. [x]๊ฐ ์์์ธ ๊ฒฝ์ฐ.
* 2-1. ๋๋จธ์ง[remainder]๊ฐ 0์ธ ๊ฒฝ์ฐ
* -> remainderIsZeroThen0Else1 ๊ฐ 0์ด๋ฏ๋ก, negative2PowerN๋ 0์ด๋ค.
* ๋ฐ๋ผ์ 0 & ??? ์ ํ์์ด๋ฏ๋ก, ๊ฒฐ๊ตญ 0์ด๋ฉฐ, ๋ํด์ ธ๋ ๊ฒฐ๊ณผ์ ์ง์ฅ์ด ์๋ค.
*
* 2-2. ๋๋จธ์ง๊ฐ 0์ด ์๋ ๊ฒฝ์ฐ
* -> negative2PowerN ๊ฐ -2^n ์ด๋ค.
* ์์๋ฅผ ๋๋ ์ค ๊ฒฝ์ฐ, ์์๋ก ๋์จ ๋๋จธ์ง์ -2^n์ ํด์ฃผ์ด์ผ ์๋ง์ ์์ ๋๋จธ์ง๊ฐ ๋์จ๋ค.
* ์๋ฅผ ๋ค์ด -35 / 8์ ๊ฒฝ์ฐ,
* 35 = 0010 0011
* -35 = 1101 1101
* 8๋ก ๋๋๋ฏ๋ก, remainderMask = 0000 0111
* ์ฆ 1101 1101 & 0000 0111 = 0000 0101 = +5์ด๋ค
* +5 - 2^3 = -3 ์ด๋ฏ๋ก, -2^n์ ํด์ฃผ์ด์ผ ์ ํํ ๋๋จธ์ง๊ฐ ๋์จ๋ค.
*
* ์ด๋ ๋ค์๊ณผ ๊ฐ์ ์์ผ๋ก๋ ํํ ๊ฐ๋ฅํ๋ฐ,
* -35 = 8 * -5 + 5 ์ด์ง๋ง, ์ด๋ฅผ ์๋์ ๊ฐ์ด ๋ฐ๊ฟ์ฃผ์ด์ผ ํ๋ค.
* -35 = 8 * -4 - 3
*/
return (remainder) + (negative2PowerN & MSBMask);
}
'๐ฅ Computer Science > ์์คํ ํ๋ก๊ทธ๋๋ฐ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์์คํ ํ๋ก๊ทธ๋๋ฐ] ์ด์ ๋ธ๋ฆฌ์ด[2] - ์กฐ๊ฑด๋ฌธ (2) | 2022.10.12 |
---|---|
[์์คํ ํ๋ก๊ทธ๋๋ฐ] ์ด์ ๋ธ๋ฆฌ์ด [1] (2) | 2022.10.10 |
[์์คํ ํ๋ก๊ทธ๋๋ฐ] ์์์ ํํ (๋ถ๋์์์ ) (0) | 2022.10.02 |
[์์คํ ํ๋ก๊ทธ๋๋ฐ] ์ ์์ ํํ (0) | 2022.09.17 |
[์์คํ ํ๋ก๊ทธ๋๋ฐ] ์ปดํจํฐ ์์คํ (0) | 2022.09.17 |