CS

이진 기수법을 통한 고정 소수점과 부동 소수점

재윤 2024. 1. 24. 15:10
반응형

이 글은 이 분의 블로그 통해 공부한 글입니다.

이진 기수법을 통한 고정 소수점(Fixed Point) 와 부동 소수점(Floating Point)

 

이진 기수법을 통한 고정 소수점(Fixed Point) 와 부동 소수점(Floating Point)

이 글은 제가 공부하기 위해 여러 사전이나, 책, 그리고 다른 개발자 분의 내용을 타이핑하여 학습한 내용이므로, 이 원본은 출처를 꼭 남깁니다. 원래내용과 살짝 다를 수 있는 점 양해바랍니다

daldalhanstory.tistory.com

 

이진 기수법(이진법에 대한 내용을 좀 더 자세하게 알고 싶으면 나의 블로그 밑 부분의 개념을 보고 오자

https://wo-dbs.tistory.com/141

 

이진 기수법(이진법)

컴퓨터는 0과 1로 이루어진 기계어를 사용한다. 우리 사람은 수를 표현할 때 10진법을 사용한다 → 10진법은 0, 1, 2, 3, 4, 5, 6, 7, 8, 9을 말함. 컴퓨터는 0과 1인 이진법으로 수를 저장하게 된다. → 이

wo-dbs.tistory.com

 

위의 글을 보고 왔으면 이제 이렇게 생각할 수 있다

→ 어? 정수는 그렇다 치더라도 실수(real number)를 어떻게 표현하지? 소수점이 붙어있는 수는 어떻게 2진수로 표현할까?

 

간단하게 해결방법을 생각해보자

 

💡 일단은 소수점 앞부분, 즉 정수부는 그냥 우리가 배운 정수 변환하는 거랑 똑같이 하면 됨. 소수점 뒤에 있는 숫자들을 하나씩 2진수로 바꿔버리면 된다. 라고 생각 가능하다.

  • 위처럼 하면 소수부가 문제가 생길 수 있다. → 서로 다른 10진수 숫자가 2진수로 변환되었을 때 중복이 되는 문제가 있다.
  • 1.9 1.41을 해본 결과값이 같아지는 문제를 밑 사진에서 볼 수 있다.

 

 

실수를 2진법으로 계산해보기

→ 위와 같은 문제를 해결하기 위해 소수부에서 10진수에 2를 곱해가면서 1이나 0을 뽑아준다.

  • 위 말이 무슨 말인지 예제를 통해 한 번 보자

ex) 68.625

  1. 정수부와 소수부를 따로 본다
  2. 정수부를 이진법으로 구한다
  3. 소수부를 이진법으로 구한다
    • 소수부 10진법의 값에 2를 곱하는데 그 결과가 1로 떨어질 때까지 혹은 똑같은 소수점이 나올 때까지 반복한다.
    • 나온 정수부를 위에서부터 가져온다.
  4. 정수부, 소수부를 합쳐준다.

실수를 이진법으로 바꾸기

이제 나온 result 값을 컴퓨터에 저장한다고 할 때 어떻게 되는지 보자 고정 소수점에서 어떻게 되는지 보자

고정 소수점(Fixed Point)

→ 이 표현 방식은 위에서 설명한 방법대로 10진수를 2진수로 바꿨으면 고대로 박아 넣는 방식

 

위에서 구한 걸 넣어보자

→ 16비트 체계를 쓴다고 가정하자.

  • 제일 1앞자리 부호 비트(Sign Bit)라고 해서, 0이면 양수, 1이면 음수라는 뜻.
  • 나머지 비트는 정수부, 소수부로 나뉜다. 소수점의 위치를 미리 정해두기 때문에 소수부의 경우 앞에서부터 채우며 남는 뒷자리는 다 0으로 채운다.

이 방법은 구현이 편리하긴 하다 하지만 정밀도가 낮기 때문에 실수를 다룰 필요가 있는 범용 시스템에서는 거의 안 쓰이고, 높은 정밀도가 필요없는 소규모 시스템에서 쓰인다고 한다.

 

부동 소수점

→ 부동 소수점은 2진수로 나온 결과값을 그냥 넣는 것이 아닌 새로운 것이 추가된다.

  1. 정규화(Normalization)

💡 정규화는 수학이나 컴퓨터 분야에서 다양한 의미로 쓰이지만 여기서 말하는 정규화라는 것은 2진수를 1.xxxx…2^n 꼴로 변환하는 것을 말한다

  • 정규화 방법은 정수부에 1만 남을 때까지 소수점을 왼쪽(정수부가 0일 때는 오른쪽)으로 이동 시키며, 이동한 칸 수 만큼 n자리에 넣으면 된다.

위에서 한 1000100.101을 정규화를 한 번 해보자.

→ 여기서 소수점을 ‘이동’시킨다는 데서 ‘부동’ 소수점, floating poing라는 용어

  • lEEE 754 부동소수점 표현 → 미국의 전기 전자 기술자 협회에서 개발한 컴퓨터에서 부동소수점을 표현하는 방법.
  • lEEE 표준에 따르면 32비트 또는 64비트가 사용됨.

32비트를 보자.

  • 부호 비트는 0이면 양수, 1이면 음수 의미
  • 23자리 가수부는 정규화 결과 소수점 오른쪽에 있는 숫자들을 왼쪽부터 그대로 넣으면 된다. 남은 자리 0으로 채움.
  • 8비트 짜리 지수부는 2^n에서 해당하는 n의 2진법의 값을 추출하면 된다.

정규화와 지수부, 가수부 구하기

위 그림에서 보듯이 가수부는 넣어주게 되었는데 중요한 개념인 지수부를 넣을 때를 잘 봐야한다. ‘지수’부라는 이름으로 봤을 땐 2^n에서 n에 해당하는 수 그러니까 6을 2진수로 바꾼 101을 넣어주면 될 것 같은데 이렇게 하면 안된다.

  • lEEE 표준에 따르면 저 부분에는 지수의 이진법을근야 넣는 게 아니라 ‘bias’라고 하는 지정된 숫자를 더한 다음에 넣어주어야한다.
    • bias : lEEE 754 표준에 있는 상수값(127) 지수에 따라 상수값이 바뀐다.
    • 이걸 왜 쓰냐? 지수가 음수가 될 수도 있음. → 밑에 좀 더 설명함.
  • lEEE 표준에서 32비트를 사용하면 bias는 127이라고 규정되어 있다
    • 6+127=133=10000101
    • 6+127=133=10000101 (127을 더하는 이유는 바이어스를 적용하기 위함.)

결론적으로 68.625는 밑 그림처럼 컴퓨터에 저장된다.

 

bias?

  • bias라는 값을 왜 쓰냐면, 지수가 음수가 될 수 있어서 그럼
  • 0.000101이라는 진수가 있다면, 정규화에 대해서 설명할 때 정수부를 1로 만들어야함. 그러면 왼쪽이 아니라 오른쪽으로 소수점을 밀어서 1.01 * 2^-4 가 된다.

bias없이 2를 그냥 00000010으로 저장했다고 하면 -4는 어떻게 저장해야될까?

→ 지수용 부호 비트를 하나 더 만들자니 이것도 복잡하다 그래서 8자리를 가지고 음수랑 양수를 둘 다 표현하자고 하니 힘들어서 그냥, 0~127구간은 음수, 128 ~ 255 구간은 양수를 표현하도록 만든 것이다(그래서 127을 더함)

32비트 체계를 32비트 단정도(Single-Precision), 64비트 체께를 64비트 배정도(Double-Precision)이라고 한다.

프로그래밍 언어에서 실수형 타입 float, double이 각각 32비트, 64비트에 해당한다.

float은 부동소수점 방식을 사용하는 기본형이라는 의미이며 floating point에서 따왔다. 그리고 double 64비트 배정도를 사용한다는 의미로 double-precision에서 따왔다고 한다.

  • double → 64비트 체계 지수부가 11비트, 가수부가 53비트
  • 지수부가 2^11 2048개 수 표현 가능 → 0~1023 구간 음수, 1024 ~ 2047 양수 지수를 의미하며 bias는 1024이 됨.

 

소수점 이진수로 변환하는 법 | 소수점 이진법

 

소수점 이진수로 변환하는 법 | 소수점 이진법

ex) 68.625 -> ??? 1. 정수부(68)는 그대로 이진수로 변환한다. 64 + 4 -> 100 0100 2. 소수부(0.625)만 가져온다. 0.625 3. 소수부에 2를 곱하는데 그 결과가 1로 떨어질 때까지 혹은 똑같은 소수점이 나올 때까지

woo-dev.tistory.com

이진 기수법을 통한 고정 소수점(Fixed Point) 와 부동 소수점(Floating Point)

 

이진 기수법을 통한 고정 소수점(Fixed Point) 와 부동 소수점(Floating Point)

이 글은 제가 공부하기 위해 여러 사전이나, 책, 그리고 다른 개발자 분의 내용을 타이핑하여 학습한 내용이므로, 이 원본은 출처를 꼭 남깁니다. 원래내용과 살짝 다를 수 있는 점 양해바랍니다

daldalhanstory.tistory.com

 

반응형

'CS' 카테고리의 다른 글

inff, inf, nan, NAN  (1) 2024.01.26
리터널, 상수  (0) 2024.01.26
이진 기수법(이진법)  (1) 2024.01.24
>>, << 쉬프트 연산 C++  (0) 2023.12.02