자바 의 부동 소수점 분석
부동 소수점 은 단일 정밀도 와 이중 정밀도 로 나 뉘 는데 자바 의 단일 정밀도 와 이중 정 도 는 각각 float 와 double 입 니 다.float 와 double 은 어떻게 저장 되 는 지 아 세 요?
float 는 4 개의 바이트,double 은 8 개의 바이트 로 편 의 를 위해 float 유형 만 논의 합 니 다.
float 는 사실 하나의 int 형의 크기 와 같 습 니 다.모두 32 자리 입 니 다.첫 번 째 는 기 호 를 표시 하고 2-9 는 지 수 를 표시 하 며 뒤의 23 자 는 소수 부분 을 표시 합 니 다.여 기 는 많이 말 하지 않 습 니 다.참고 하 시기 바 랍 니 다.http://blog.csdn.net/treeroot/archive/2004/09/05/95071.aspx여기 서 예 를 들 어 벽돌 을 던 져 옥 을 끌 어 올 리 기 를 바 라 는 것 은 바로 부동 소수점 0.1 의 저장 형식 을 연구 하고 이 프로그램 을 먼저 실행 하 는 것 이다.
public class Test{
public static void main(String[] args) {
int x = 0x3d800000;
int i = 1 << 22;
int j = 1 << 4;
float f = 0.1f;
int y = Float.floatToIntBits(f);
float rest = f - ( (float) 1) / j;
while (i > 0) {
j <<= 1;
float deta = ( (float) 1) / j;
if (rest >= deta) {
rest -= deta;
x |= i;
}
i >>= 1;
}
pr(x);
pr(y);
}
static void pr(int i) {
System.out.println(Integer.toBinaryString(i));
}
}
결과:
111101110011001100110011001101
111101110011001100110011001101
프로그램 설명:
int x=0x3d80000;
부동 소수점 표시 형식 이 1.f*2n-127 이기 때문에 우 리 는 0.1 을 표시 해 야 한다.n-127=-4,n=123 까지 알 수 있다.
기 호 는 플러스 이 고 앞의 9 는 001111011 임 을 알 수 있 으 며 뒤의 23 비트 소 수 를 잠시 고려 하지 않 기 때문에 우 리 는 먼저 x=0x3d 800000 을 가설 합 니 다.
int i = 1 << 22;
i.처음에 오른쪽 부터 23 위 는 1 이 고 x 의 10 위 이다.
int j = 1 << 4;
i.처음에 4 였 습 니 다.n-127 은-4 이기 때문에 여 기 는 그것 의 역 수 를 구하 기 위해 서 입 니 다.
float f = 0.1f;
int y = Float.floatToIntBits(f);
y 가 32 분 입 니 다.
float rest = f - ( (float) 1) / j;
이 rest 는 1.f 중 1 을 제외 하고 0.f 라 는 뜻 이다.
while (i > 0) {
j <<= 1;
float deta = ( (float) 1) / j;
if (rest >= deta) {
rest -= deta;
x |= i;
}
i >>= 1;
}
이 순환 은 23 비트 소수 부분 을 계산 합 니 다.rest 가 deta 보다 작 지 않 으 면 이 자 리 를 1 로 설정 할 수 있 음 을 표시 합 니 다.
다른 것 은 더 이상 말 하지 않 겠 습 니 다.입력 결 과 는 같 습 니 다.0.1 이 부동 소수점 은 정확 하지 않 을 것 이 라 고 할 수 있 습 니 다.하지만 0.5 는 왜 그런 지 정확하게 표시 할 수 있 습 니 다.생각해 보 세 요.