본문 바로가기

JAVA(CodeLatte강의)/기타

실수는 어떻게 표현될까?

[ JAVA에서 10과 10.0은 같을까? ]

같지 않을수 있다.

왜냐하면 int나 short같은 정수랑

float나 double같은 실수의 표현방식이 다르기 때문이다.

 

[ 왜 정수랑 실수의 표현 방식이 다를까 ? ]

소수라는 성질때문에 그렇다.

무한소수인 경우 소수점이 끝없이 있을것이며

유한소수인 경우라도 50자리 까지 있을수도 있다.

그러면 컴퓨터는 무한개의 bit나

50개의bit를 제공해야 할까?

그럴수 없다 컴퓨터의 메모리는 한정적이다.때문에 실수는 데이터의 저장방식이 정수와 다르다.

 

 

[ computer에서 실수 표현 방식 ]

소수점이 고정된 고정소수점방식과

소수점이 이동하는 부동 소수점 방식이 있다.

JAVA에서는 부동 소수점 방식이다.

 

[ 부동 소수점의 표현 방식 ]

부호bit + 지수부bit + 가수부bit로 구성된다

float의 지수부bit는 8bit 가수부bit는 23bit

double의 지수부 bit는 11bit 가수부 bit는 52bit이다.

 

[ float타입 10.0 의 부동 소수점 저장과정 ]

1) 정수 부분 추출

- 10을 추출한다

2) 추출한 정수를 이진수로 변환

- 1010

3)소수 부분의 2진수 추출

- 0[ 

ex) 만약 10.2였다면

     소수 부분에 0이나올때까지 2를 곱해준다

     2를 곱한 결과값이 1이넘으면 1저장

     넘지않으면0을저장한다

이것은 소수점을 끝까지 계산하는것과 같은 원리다.

4) 정수와 소수부분 연결

1010.0000 / 0000 0000 / 0000 0000 / 0000 0000

5)소수점을 맨앞으로 이동

1.010 0000 / 0000 0000 / 0000 0000 / 0000 0000

6)최상위 bit 제거

.010 0000 / 0000 0000 / 0000 0000 / 0000 0000

7) 23번째 bit까지만 저장

0100 0000 / 0000 0000 / 0000 000

8) 3(소수점이 이동한 자릿수) + 127(32bit Bias 체제)

130

9) 130을 2진수로 표기

10000010(2)

10) 1bit(부호) + 8bit(지수부) + 23bit(가수부)

0 1000 0010 / 010 0000 / 0000 0000 / 0000 000

 

[ 생각정리 ]

5) 에서 소수점을 맨앞으로 옮기는 과정은

뒤에 2^양수 또는 2^음수 를 곱해주는 과정과 같다

이 양수와 음수에 사용된 지수가

Bias방식으로 추출된 지수부 이다.

 

6) 에서 최상위 bit를 자른건 

최상위 bit는 무조건 1이기에

효율적인 메모리 관리를 위해 잘랐다.

때문에 가수부를 계산할때는

2^0 있다고 생각하고 2^-1부터 계산한다

 

8) 에서 127을 더해주는 이유는

양수의 지수와 음수의 지수를 표현하기 위해서다8bit를 통해서 2^0~255까지 표현 가능한것을양의 지수 2^127음의지수 2^128 까지 표현하기 위해서였다.

 

( 여기서 이해하지 못한부분은

  1bit당 2^n 을표현하는 것이아닌

   bit가 만들어낼수 있는 정수의 범위만큼

   지수를 표현 한다는 것이다 )

 

계속 설명하자면

+127 을 더해주는것은

지수부의 표현범위가

2^0~2^255 까지였던것을

2^127 ~ 2^-128로

변경해주는 것과 같다고 생각해도 된다.

또 2^0 을 2^(-127)로 변경하는것과 같다고 생각해도 된다.

때문에 32bit체제에서의 bias는

8bit를 정수로 저장하는데 사용되고

그 정수는 2^127~2^(-128)

범위에 해당하는 양/음의 정수를 저장할수 있다.

 

[ 0 1000 0010 / 010 0000 / 0000 0000 / 0000 000 은 정수 10과 다른가? ]

 

1) 부호비트 제거

1000 0010 / 0100 0000 / 0000 0000 /0000 000

2)지수부 가수부 분리

1000 0010 / 0100 0000 0000 0000 0000 0000

3)지수부 10진수의 값으로 변환

1000 0010 > 130

4) 130(지수부 10진수값) - 127 (32bit Bais 체제)

3  (이제는 이것이 2^3을 의미 한다는것을 알수 있다)

5) 가수부 앞에 1bit추가 ( 이전에 1. 을 삭제했었기 때문에)

1.010 0000 / 0000 0000 / 0000 000

6) 2^3만큼 부동소수점 이동

1010. 0000 / 0000 0000 / 0000 000

7)가수부 계산

2^3 + 2^2 + 2^1 + 2^0 + 2^(-1) + ~~ + 2^(-19) 

 

만약 지수부의 범위가 2^2 였다면

가수부는 2^(-20)까지 표현 가능했을 것이다.

이것이 부동소수점에 장점이다

지수부를 불필요하게 쓰지않으면서

가수부의 표현범위를 유연하게 늘리는것이다.

인느 곧 메모리 관리에 긍정적인 영향을 준다.

=> 10.0

 

[ 자바 언어에서는 최대 정밀도 기준으로 반올림을 한다 ]

정밀도는 오차없이 표현가능한 수치이다

최대정밀도가 8이라면

정수부분+소수부분 을합쳐

8자리까지는 정확하게 표현한다 는것이다

9번째 의 소수는 반올림이된다.

 

[ 느낀점 ]

 

실수를 데이터에 저장하고

저장한 값을 실수로 불러오는 과정에서

반올림을 하기때문에 

값을 근사값이라고 표현하는 것을 알았다.

 

하지만 아쉬운점은 계산했을때

10 과 10.0 이 같다 ( 내가 공부한게 맞다면 )

예전에 1과 1.0은 다르다고 들었을때

정말 궁금했었는데

10.0을 저장했을때랑

데이터로 불러왔을때랑 같아서 아쉽다.

 

계산과정을 보면 같지 않을 것 같은데

아직 정확하게 이해하진 못하고 있다고 생각된다.

'JAVA(CodeLatte강의) > 기타' 카테고리의 다른 글

bit로 무엇을 할까?  (0) 2021.08.20