IEEE 부동소수점 총 정리
IEEE 부동소수점 총 정리 — #IEEE부동소수점 #부동소수점 #개발자의도구들 컴퓨터공학과 학사과정 중 공부한 내용을 정리하였습니...
#IEEE부동소수점 #부동소수점 #개발자의도구들
컴퓨터공학과 학사과정 중 공부한 내용을 정리하였습니다.
\* 본글은 PC버전에 최적화 되어있습니다.
2진수 소수구하기
10진수 소수를 2진수 소수로 변경하는 방법을 알아봅시다.
- 정수부와 소수부를 나눕니다.
- 아래 식을 적용합니다.
- 다시 합칩니다.
🙅문제점: 위 방법은 2의 배수로 나눠 떨어지는 수만 정확하게 표현이 가능합니다. 예를들어 3이나 5로 나눠 떨어지는 수를 표현하기에 한계가 존재합니다.
1/3 = 0.0101010101\[01\]...
1/5 = 0.001100110011 \[0011\]....
고정 소수점 표현
위의 식으로 구해진 소수를 컴퓨터로 표현하기 위해서는 여러 방법이 동원됩니다. 가장 첫번째로 알아볼 소수표현은 바로 고정 소수점입니다.
예를들어 실수(정수 + 소수)를 8비트로 표현하기로 했다고 가정해봅시다. 이때 101.0111을 8비트내에서 할당하려면 딱 맞게 표현이 가능한데요.
근데 여기서 문제는 소숫점 고정 포인터가 항상 변경되며 어디에 있는지를 따로 기억하고 있어야 한다는 것 입니다. 그럼 이번에는 11001.011111로 고정 소숫점으로 표현해보겠습니다.
제한된 8비트 내에서 수를 표현하려다 보면 두가지 문제가 생깁니다.
첫번째는 왼쪽 케이스처럼, 정확한 수표현을 하다보면, 정밀한 소수부분을 버려야한다는 것입니다.
두번째는 오른쪽 케이스처럼, 너무 정밀하게 소수 부위를 표현하려다 보니, 실제 수와 너무나 큰 차이가 나는 수로 표현된다는 것입니다.
이런 방법으로 수가 잘려나가다 보니 다른 환경에서 사용하기 까다로워 지는데요. 소숫점 위치도 다를 뿐더러, 수가 전달되었다 해도, 원래 수 와 다를 가능성이 존재하기 때문이지요.
IEEE floating point standard
이를 해결하기위해 1985년, IEEE에서는 standard 75 Floating point에 대한 표준을 발표하였는데요. 현재까지도 표준으로 사용될만큼 유연한 소숫점 표현을 지원합니다.
흔히 부동소수점이라고 불리는데, 이는 부동의 한자가 浮 뜰 부 動 움직일 동으로 소숫점이 계속 떠서 다닌다는 의미가 들어가 있습니다. (floating)
표기방법
IEEE에서 정의한 Floting Point 표준은 32비트를 사용하여 소수를 나타냅니다. 32비트를 3부분으로 나눠서 각각의 역할을 부여하였습니다. 아래식을 함께 보시죠.
위 수식을 통해 소숫점을 표현하는데요. 위에서 변수들이 3개인거 보이시나요? 각 변수들은 3등분으로 나뉜 부분을 의미하며, 표준에따라 각각 비트의 크기도 다릅니다.
s: Sign bit로 양수인지 음수인지 결정하는 비트가 되겠습니다.
M: significand M으로 假數 즉 사용로그의 지수, 가수할때 그 가수입니다. 유효한 숫자를 의미한다고 보시면 되는데, 실제 소수의 값을 표현하는데 사용됩니다. Floating Point에서는 \[1.0, 2.0)의 범위를 가집니다.
E: Exponent의 약자인 E는 지수 표현으로 2의 거듭제곱을 저장하는 공간입니다. 밑의 Normalized에서 다시 설명하겠습니다.
Precision options
정밀도 조정으로, 부동소숫점을 32비트, 64비트, 80비트로 조정하여 사용이 가능합니다.
당연하게도 정밀도가 높을수록, 즉, 많은 비트를 사용할 수록 표현하는 숫자의 정확도는 올라갑니다. 보통은 32비틀 일반적으로 많이 사용하니, 각 부분에 해당하는 비트수를 외워두시는게 좋습니다.
Normalized
일반적읜 형태로 exp, 즉 지수부분이 0000 0000이 아니거나 1111 1111이 아닌 형태를 말합니다.(32비트 기준으로 설명합니다)
아까 위에서 이와 같은 식을 보셨는데요. 여기서 E는 M에 2의 거듭제곱을 곱한 형태입니다. 이를 이해하기 위해 정규화 과정에 대해 알아야할 필요가 있는데요.
어떤 수를 이진수 소수 표현으로 변경하고보니, 101.110001 이 되었다고 가정해봅시다. 이제 이 소수 표현을 위식에 대입되는 형태로 변경을 해야하는데요. 이때 필요한게 정규화(Normalized) 과정입니다.
실제값은 101.110001이지만, 정규화를 거치면 1.xxxx 형태로 변경됩니다. 즉, 1.01110001이되는 것이지요. 이때 원래값의 정수부분을 101임을 기억하기 위해 E값이 2가되는 것이죠. 1.01 \* 2^2 = 101.
하지만, Single precision에서 소숫점 표현을 보시면 E를 사용하는 것이 아니라 exp를 사용하고 있습니다.
이는 E를 통해서 구할 수 있습니다.
우리는 지금 E를 알고 잇으니 Bias만 구하면 되겠네요. Bias는 다음과 같은 식을 통해 구해집니다.
이때 k는 exp를 사용하기로 한 비트수로 이해하시면 편합니다. 즉 Single precision에서는 127이되고 Doulble의 경우에는 1023이 되지요.
직접 구해보기
구하는거 식으로 표현
Denoramalized와 Special Value
Denormalized
32비트 사용
single precision의 exp부분이 0000 0000이라는건 어떤 의미일까요?
exp = E + 127(bias)로 표현되는데,exp가 0이라는 것은 E가 -127가 되는 것일까요?
실제로 exp가 모두 0이고, frac(가수)부분이 0이 아니라면, E는 아래와 같은 식으로 계산됩니다.
여기서 의아한 것은 exp가 분명 0000 0000이었는데 갑자기 1로 바뀌었다는 것입니다. 이는 가장 작은 정규화 값에 이어서 수표현을 지속하기 위함입니다. (자세한건 다음에 다뤄)
Special Values
32비트 사용
모든 exp의 값이 1로만 구성되어있는 경우.
exp = 1111 1111이고 Frac(가수 부)가 모두 0000... 인경우에는 정규화된 수 범위를 넘어서는 지수 값을 표현합니다. 이는 무한대로 표기됩니다.
exp = 1111 1111인데 Frac이 하나라도 1의 값을 같는다면, 이는 NaN오류가 나도록 설정 되어있습니다.
예시 케이스
비트수를 낮춰 생각해 봅시다. 예를 들어 8비트 플로팅 포인트를 사용한다고 가정하겠습니다.
이 경우 S를 1비트 exp를 4비트, frac을 3비트로 표현합니다. exp가 4비트이기 때문에 bias는 7이 됩니다.
이수가 가질 수 있는 모든 경우의 수는 아래와 같습니다.
이때 normalize와 Denormalized의 경계선을 보면 exp가 0001에서 0000으로 변경되며, frac의 값은 최소 (000)에서 최대(111)로 변환되는 것을 알 수 있습니다. 앞서 말씀드렸다 싶이, 이는 정규화와 비정규화 사이의 간격을 두지 않고 이어서 표현이 가능하게 설정해 둔 것 입니다.
Floating Point Operations
부동 소수점의 연산
부동소수점 덧셈
덧셈을 위해서는 다음과 같은 연산 순서를 따릅니다.
1.0110 x 2^3 + 1.1000 x 2^2
- 2진수 지수를 맞춘다.
1.0110 x 2^3
+ 0.1100 x 2^3
- 가수 부분을 더한다.
10.0010 x 2^3
3. 정규화
1.0001 x 2^4
- 반올림 (아래 정리)
부동소수점 곱셈
- 지수끼리 더하기
(1.0110 x 2^3) X (1.1100 x 2^2)
127 + 3 = 130
127 + 2 = 129 - 127
- 가수끼리 곱하기
- 결과를 정규화 하기
- 부호확인
Round(반올림)
부동 소숫점에는 여러가지 반올림 표준이 존재하는데, defaul로 사용되는 것은 Nearst Even이다. (가장 정확도가 높음)
Towards zero
Towards zeor는 이름에 걸맞게 0과 가까운 쪽으로 반올림 하는 것이다.
1.4 -> 1
1.6 -> 1
2.4 -> 2
-1.4 -> -1
-3. 5 -> -3
양수에서는 내려지고, 음수에서는 올려지기만 하는 것을 볼 수 있다.
Round down
우리가 알고 있는 내림과 동일하다. 무조건 본인 보다 작은 정수로 내린다.
1.3 -> 1
4.5 -> 4
-3.4 -> -4
-4.7 -> -5
Round up
Round down의 반대 개념이다. 우리가 알고 있는 올림과 같은 동작을 한다.
1.3 -> 2
4.5 -> 5
-3.4 -> -3
-4.7 -> -4
Nearst Even
생소한 개념이긴한데, 두가지 측면에서 고려해야한다.
- 0.5가 아닌 경우
소숫점이 0.5가 아닌 경우에는, 가까운 정수로 올라가거나 내려간다.
- 0.5인 경우
여기서 조금 특별하게 작용하는데, 0.5일때는 가까운 정수로 이동한다.
1.5 -> 1하고 2, 2가 짜굿라서 2로
4.5 -> 4하고 5, 4가 짝수라서 4로
가장 오차가 적어 Default mode로 사용됩니다.
| System.out.print형식없이 출력 |
|---|
println
| System.out.println형식없이 출력 후 다음 줄의 처음으로 이동한다.커서의 위치가 처음이 됨을 의미 |
|---|
C에서의 floating Point
float = single precision (32bit)
double = double precision (64bit)
double이 더 정밀하다.








