달력

092018  이전 다음

  •  
  •  
  •  
  •  
  •  
  •  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  •  
  •  
  •  
  •  
  •  
  •  

'IEEE 754'에 해당되는 글 1건

  1. 2011.08.11 IEEE 754 single precision : binary32
참조 :  IEEE 754 floating point Wiki  ,   IEEE 754 blog  ,    정수를 넣으면 어떻게 비트변환이 되는지 보여줌

어떻게 변환되는지 단계별로 잘 설명한사이트

위의 자료를 통하여 IEEE 754가 어떤 규칙을 통해 부동 소수점을 표현하는지 알게 되었다.
소수부분에서 10진수를 2진수로 변환하는 걸 나는 아래와 같이 생각하고 있었다.
float input;
printf("input converting float Number :");
scanf("%f", &input);

char binary[15+1];
int binary_idx;
float fraction = 0.5f;
binary_idx = 0

while (input != 0.0f && binary_idx < 15) {
	if (input >= fraction) {
		binary[binary_idx] = '1';
		input -= fraction;
	}
	else 
		binary[binary_idx] = '0';
	fraction /= 2;
}
binary[binary_idx] = '\0';
printf("bit : %s\n", binary);
0.5, 0.25, 0.125를 원래정수에 빼보면서 0이 나올때까지 loop를 돌리는것이다.


그런데 이것 저것 예제를 보다가 다른 방법으로 구하는게 있어서 그것대로 구현을 해봤다.

다른점은 나누기/곱하기 연산.....그리고 fraction 유/무
괜시리 곱하기 연산이 나누기 연산보다는 빠를것 같다. 캬.....수학....;;


다시 IEEE754로 와서
Not-a-Number 는 아래와 같다. 숫자가 아니라는거.
±0 ÷ ±0 NaN
Infinity - Infinity NaN
±Infinity ÷ ±Infinity NaN
±Infinity × 0 NaN

NAN은 아래와 같이 표현 한다고 한다.
 
0 11..11 00..01
:
01..11
SNaN
0 11..11 10..00
:
11..11
QNaN
1 11..11 00..01
:
01..11
SNaN
1 11..11 10..00
:
11.11
QNaN

이걸 학습한 본래의 목적은 아래와 같은 결과가 나와서 왜?? 그런지 또 어떻게 하면 해결할수 있을지에 대한 의문을 풀기 위함이었다.
 
byte input = 'F';
input = SmallFloat.floatToByte315(0.75f);
System.out.println("input :" + input);
System.out.println("finput :" + SmallFloat.byte315ToFloat(input));
//결과 : input :122
//         finput :0.75


byte input = 'F';
input = SmallFloat.floatToByte315(0.75f);
System.out.println("input :" + input);
System.out.println("finput :" + SmallFloat.byte315ToFloat(input));
//결과 : input :121
           finput :0.625
왜 저런 수가 나왔는지는 간단하게 살펴보면~!!    (0.75만;; 귀차니즘....허허허)

0.75를 2진수로
0.75 * 2 = 1.5   (1)
0.5  * 2  = 1.0   (1) 
0.75(10) ->  0.11(2)       nomalize :    1.1 * (2^-1)   
Mantissa  :  1                Exponent : (-1) + 127 = 126      Sign bit = 0
so  0011 1111   0100 0000   0000 0000   0000 0000
아래 함수에서 bits에 0011 1111   0100 0000   0000 0000   0000 0000값이 저장되고 return결과가 122
 

public static byte floatToByte315(float f) {
    int bits = Float.floatToRawIntBits(f);
    int smallfloat = bits >> (24-3);
    if (smallfloat < (63-15)<<3) {
      return (bits<=0) ? (byte)0 : (byte)1;
    }
    if (smallfloat >= ((63-15)<<3) + 0x100) {
      return -1;
    }
    return (byte)(smallfloat - ((63-15)<<3));
 }

0.74는 0.5  (1) + 0.25  (0) + .....계속 가다보니 23bit 를 넘어섰고 Mantisa의 범위, 23개에서 자른것이다.
결국 뭐 float이란게 int같이 정확한 수 개념이 아니라 대충 이럴거 같다, 라는 것이기 때문에 위에처럼 원하는 결과를 얻지 못하는것이다. 


그럼 어떻게 풀어 나가면 좋을까?  0.75, 0.625, 0.5는 자르는것 없이 정확하게 표현이 된다.
결국 그 사이에 있는 값들이 문제라는건데,
생각난건, 1bit를 어느쪽에 가깝냐.....라는 bit로 사용하는건 어떨까?
1 이면 현재 Mantisa범위에서 윗단계와 가깝고, 0으면 그냥 현재 Mantisa범위와 같다....
이렇게 하면 0.74도 0.75로 나오지 않을까.......


조사한건 많았는데 막상 이렇게 블로그에 올리려고 하니, 주저리 떠들기나 하고있다.
아직 완벽하게 이해하지 않는것 같다...;;; 씁쓸하네...

Posted by 오산돌구