TIL - 2021.09.28

Wanna be __·2021년 10월 4일
0

TIL

목록 보기
37/45
post-thumbnail

Today, I Learned

1. CA

Floating Point**

1. Representation

s/Exp/Frac로 나타내고, Exp는 E + bias로 나타냄.
Single Precision의 경우 각각 1/8/23 bits로 표현됨.
Bias는 2^(k-1)-1 즉, exp의 자리에서 MSB만 제외하고 전부 1로 된 값임.

표현할 수 있는 수의 범위
0 / Denormalized Values / Normalized Values / NaN / Infinity 임.

Exception들

  1. Exp가 모두 0인 경우
  • Frac이 모두 0이면 0
  • Frac이 모두 0은 아니면, Denormalized Value이고, 이때 E는 0-Bias 가 아니라, 1-Bias임.
  1. Exp가 모두 1인 경우
  • Frac이 모두 1은 아니면, NaN -> 이것과 연산한 모든 결과값은 NaN임

  • Frac이 모두 1이면 Infinity.

    각 E값마다 구간이 정해지는데(2^E <= x < 2^E+1)
    그 구간마다 동일한 개수의 수를 표현할 수 있음 (2^(Frac bits)으로 표현할 수 있는 수만큼..!)
    그리고 Sign bit로 양/음 표현할 수 있으니 0도 2개고, 표현하는 범위도 양/음 두배임.

특이한 수 정리 (Value는 single precision 기준)

  1. Zero - Exp: 00000000, Frac: 0000...0000, Value: 0.0
  2. Smallest denormalized Value - Exp: 00000000, Frac: 0000...0001, value: 2^-23 * 2^-126 = 2^-149
  3. Largest denormalized Value - Exp: 00000000, Frac: 1111...1111, value: 1.0 * 2^-126 = 2^-126(보다 쪼금 작음)
  4. Smallest normalized Value - Exp: 00000001, Frac: 0000...0000, value: 1.0 * 2^-126
  5. One - Exp: 01111111, Frac: 0000...0000, value: 1.0
  6. Largest normailized Value - Exp: 11111110, Frac: 1111...1111, value: 2 * 2^127 = 2^128 (보다 쪼금 작음)
  7. NaN - Exp: 11111111, Frac: At least one 1's,v value: NaN
  8. Infinity - Exp: 11111111, Frac: 1111...1111, value: Infinity

2. Round

다양한 Round하는 방법들
1. Round up
2. Round down
3. Round toward zero
4. Round to even

우리는 4번을 할것!
bbbbbbbL|RS 에서 L, R, S값에 따라서 round하면 됨!

Case1. R = S = 0
가장 단순한 케이스. L값에 상관없이 이미 그 수를 정확하게 표시하고 있는 것.

Case2. R = S = 1
무조건 round up을 하는 케이스. 당연히 0.5보다 value가 크기 때문임.

Case3. R = 0, S = 1
무조건 round down을 하는 케이스. 당연히 0.5 보다 value가 작기 때문임.

Case4. R = 1, S = 0
L값에 따라서 Case를 나눠야 하는 경우임.
1. L = 0
이미 Even.5 이므로 뒤에꺼 그냥 버리면 됨.
2. L = 1
Odd.5 이므로 L에 1 을 더해주면서 even으로 만들어 줘야함.

int main() {

   int a = 123456789;

   int nfa;
   float fa;
   char * pa, *pfa;

   fa = (float) a;
   nfa = (int) fa;

   pa = &a;
   printf("a: %d\n", a);
   for(int i = 3; i >= 0; i--){
       for(int j = 7; j >= 0; j--){
   		int bit = *(pa + i) >> j & 1;
           printf("%d", bit);
       }
       printf(" ");
   }
   printf("\n\n");
   printf("====================\n\n");

   pfa = &fa;
   printf("fa: %f\n", fa);
   for(int i = 3; i >= 0; i--){
       for(int j = 7; j >= 0; j--){
   		int bit = *(pfa + i) >> j & 1;
           printf("%d", bit);
       }
       printf(" ");
   }
   printf("\n\n");
 }

int a는 00000111 01011011 11001101 00010101

이것을 exp와 frac으로 나누면,
00000111 01011011 11001101 00010101 -> Frac이 될 부분.
1.11010 11011 11001 10100 010 101 인데 소수점 26글자니깐 round해야함.
LRS = 011이니깐 round up 해야하고, 결과적으로 frac = 11010 11011 11001 10100 011 임
Exp = 26 + 127 = 150 = 10011001
frac = 11010110111100110100011

결과적으로 round된 float = 0 / 10011001 / 11010110111100110100011 임

원래 값은 111010110111100110100010101 인데,
round 후 111010110111100110100011000 으로 변경된거니, 8-5 = 3만큼 차이가 난다.

3. ADD/MULTIPLY operate

Pipeline을 따라 연산을 함.

ADD Operation
1. E1-E2 만큼 M2를 shift right 하고 둘을 더함.
2. 표현할 수 있는 bits에 맞게 round-to-even해줌
3. Normalized가 필요한 경우 normalze 해줌
4. 3결과에 따라서 필요하다면 다시 round와 normalize해줌

MULTIPLY Operation
1. E는 그냥 더해줌
2. M은 M1 * M2 해줌
3. M값에 따라서 normalize 다시 해줌.
4. 3결과에 따라서 필요하다면 다시 round와 normalize해줌
5. 부호 결정

Byte Ordering

  • List나 String에서 ordering이 깨지는게 아니라, int 등을 저장할때 일부 Intel CPU는 littel endian을 사용한다는 것.
profile
성장하는 개발자

0개의 댓글