예시를 통해 알아보자.
+6132.789 = 0.6132789 * 10^4는 같은 식인데 표현하는 방법이 다른 것이다.
0.6132789에서 0.6132789는 Mantissa, 뒤에 4는 exponent라고 한다.
이걸 일반적인 표현식 : m X r^e라고 나타낸다. (m은 Mantissa, e는 exponent)
< 이진수 >
+1001.11에서 소수점을 소수점을 왼쪽으로 4번 밀면 .100111 x 2^4 (4번 소수점의 위치를 옮겼으니깐)
m = 01001110 (in 8bits) sign비트 -> 양수이기 때문에 맨 앞에 0을 붙이고 뒤에 100111을 붙인다. 그리고 남은 자리는 0으로 채운다.
e = 000100 (in 6bits) sign비트 -> +4를 6비트의 2진수로 표현
음수인 경우
-1001.11를 똑같이 (r=2)의 식으로 나타내면, -.100111 x 2^4가 된다
m = 11001110 (in 8bits) -> 음수이기 때문에 맨 앞에 1을 붙이고 뒤에 100111을 이어 붙인다. 남은 자리는 0으로 채운다.
e = 00100 (in 6bits) -> +4를 6비트로 4로 표시, 마찬가지로 4는 양수이기 때문에 맨 앞에 0을 붙이고 남은 5자리를 4의 이진수로 나타내어주면 된다.
왜 맨 왼쪽에 있는 비트가 가장 중요하냐? 자리수에 따라서 가중치를 갖고 있다. 가중치의 값은 왼쪽으로 가면 갈수록 커진다. 예를 들어서 00111101맨 오른쪽에 있는 1은 2의 0승 가중치, 하지만 그 왼쪽의 경우의 값들이 더욱 커지게 된다. 그래서 제일 왼쪽에 있는(sign비트 제외) 값이 0이냐 1이냐에 따라 매우 큰 값의 차이를 가진다. 가장 오른쪽에 있는 비트는? 가장 덜 중요한 비트, 이 위치의 값이 바뀌더라도 큰 가중치 차이를 야기하지는 않는다.
ex) 350 : 맨 왼쪽 비트가 3, 0이 아니다. 그러므로 정규화된 표현이다
00035 : 정규화되지 않았다.
이진수의 경우도 마찬가지이다.
00111101의 경우 맨 왼쪽 비트를 sign비트라고 하고, 그 다음 비트가 most significant bit인데 그게 0이다. 따라서 아직 정규화되지 않았다. 0이 아닌 값이 되게 하려면? 왼쪽으로 하나씩 shift시키면 된다. 그러면 01111010이 된다. 그리고 shift시켰다는 것을 exponent부분에 반영을 해주어야한다. 아까 4였다고 하면, 이제는 3으로 바뀌었다.
소수점은 항상 맨 왼쪽에 (sign비트 제외)에 있다고 가정하고 이야길 한다.
일반적으로 floating-point arithmetic은 하드웨어에 의해서 처리되는게 일반적이다. 그렇지 않은 경우에는, 이것들을 처리해주는 subroutines들을 가지고 있어 이것들을 이용해 수행한다.
1) Gray code:
한 숫자와 근접한 다른 숫자 사이에는 오직 한 비트만 차이가 난다. 이러한 특성에 부합하면 Gray code
ex) 3은 0010, 3과 인접한 수 2는 0011 -> Gray code 특성에 만족한다.
하나 기억해야할 것 위 표 모양에서 15와 14는 Gray code 특성에 부합하지만, 15와 0도 Gray code 특성에 만족한다.
많이 사용되는 경우, 아날로그 디지털 컨버터(아날로그 신호를 디지털 신호로 변환시킬 때)
한 숫자와 다음 숫자 그거를 표현해주는 데 있어서 한 비트만 바뀌면 다음 숫자로 변환시킬 수 있다 -> Gray code 특성
2) Weighted Code : 자리수에 따라서 가중치를 갖고 있는 숫자들, 항상 4비트로 만들어진다.
ex) 2421, 왼쪽에서부터 2라는 가중치 4라는 가중치 2라는 가중치 1이라는 가중치
84-2-1 각 자리수가 8,4,-2,-1이라는 가중치를 갖고 있음
2421 코드에서 항상 5라는 숫자를 표현할 때는 1011 이걸로 표현한다. 이건 기억하라고 하심
3) Self-complementary code (보수값을 쉽게 구할 수 있다)
이런게 Self-complementary code코드에 속한다고 한다. Excess-3 code, 2421, 84-2-1 code
Excess-3 code : 3추가 코드라고 이야기한다. 항상 3추가 코드
0을 보면 0000인데 여기에 3을 더한 0011을 Excess-3에서 0으로 정의한 것, 다른 숫자들도 마찬가지
여기에 한 단계 더 나아가면 Excess-3 gray code를 만들 수 있다. 이걸 왜 만들었을까?
-> 일반적으로 사람은 10진수를 사용한다. 거기에 익숙하다. 0-9까지가고 다시 0으로 간다. 근데 BCD코드에서는 이 방식으로 사용하지 않는다. 그래서 9에서(1101) 0으로(0000) 갈 때 3비트나 차이가 난다. 그래서 이러한 경우에 Excess-3 gray code를 사용하면, 0은 0010, 9는 1010 한 비트만 차이난다. 이러한 장점이 있기 때문에 사용한다
여기서 설명하는 코드는 Self-complementary code(알아서 보수를 구할 수 있는 코드) : (r-1)의 보수를 쉽게 구할 수 있다
ex) 395를 2421코드로 설명하면 (0011 1111 1011)로 표현하고 이래놓고 395의 9의 보수를 구하면 각 자리에서 9에서 빼준다. 604에 해당하는 2421코드로 찾으면 (1100 0000 0100)이다. 하나 하나 찾을 필요없이 아까 찾은 395의 2421코드를 0과 1을 교환하면 바로 보수값을 찾을 수 있다.
Excess-3 code를 통해서 위에 과정을 반복해도 똑같이 나온다는 걸 알 수 있다.
2) parity bit : Error Detection Code에서 가장 간단한게 parity bit를 사용하는 것이다.
paraity bit : 전송하고자 하는 데이터가 몇 비트이든지 상관 없이 parity bit만 추가해서 전체적으로 1의 개수가 홀수개로 맞춰지면 odd parity, 짝수개이면 even parity라고 이야기를 한다.
3) 송신하는 쪽에서 보내자 하는 정보들의 1이 몇 개인지 확인을 한다. 만약 odd parity를 보내기로 했는데 개수를 직접 세어보니 even이라면 parity를 사용하여 홀수개로 만들어 송신한다.
오른쪽 아래 표를 예시로 보면 보내고자 하는 정보는 xyz 3비트짜리 정보이다. 그러면서 왼쪽 회로도의 Parity generator와 Parity checker 사이 존재하는 비트를 Parity bit라고 하는데 이것을 뭐로 해줄 것이냐, xyz의 1의 개수가 짝수이면 parity bit를 붙여주어야하기 때문에 1, 이미 홀수개이면 0 -> 이게 odd parity /// even parity는 반대로 작동
왼쪽 회로도 그림은 odd parity를 만들어 주는 것.
ex) 011 -> yz가 11이므로 xor -> 0이 나오고, 아까 x가 0 xor해서 0 나오는데 not 게이트가 있어서 1로 출력값이 나온다.
xyz - 011, parity bit 1 이렇게 전송, 만약에 중간에 x가 0에서 1로 바뀌었다고 하면, 수신하는 쪽에서 111 parity 1 이렇게 받았을텐데, 11 xor 들어가서 0 나오고, 1하고 0 xor에서 출력값 0이 나온다. xor해서 출력값 0나와야 하는데 not 게이트 때문에 1이 나와 Error indication이 1이 되어 1의 개수가 짝수가 되어 오류가 발생했다는 것을 알 수 있다.
parity generator와 parity checker를 조금만 바꿔주면 even parity Error Detection Codes를 만들 수 있다.
parity bit의 장점은 보내고자 하는 정보 길이에 상관없이 한 비트만 추가해서 넣어주면 된다.
단점은 위에 오류 검출은 하나의 비트 값이 바뀌었을 때 검출할 수 있었지만 만약 2개의 비트값이 바뀌게 된다면 오류 발생을 알 수 없다.
-> 쉽고 단순하지만 부정확한 특징을 가지고 있다.