되자!백엔드개발자
JAVA(자바) - double에 오차 원인/ 주의할점 본문
double 에 오차가 있는 이유
컴퓨터는 모든 숫자를 2진수로 관리한다.
실수형인 Double 또한 2진수로 저장이 되고 구조는 다음과 같다.
각 부분마다 어떤게 들어가는지는 예시로 확인하면 된다.
ex) 271(10진수) -> 10111001(2진수) -> 1.0111001 * E7 로 바꾸어 저장
=> sign = 0 / exponent = 7(111) / mantissa = 0111001 / 소수점 앞은 무조건 1이기 때문에 저장하지 않는다.
double 과 foat모두 mantissa자리에 한계가 있기 때문에 숫자가 클 경우(즉, 소수점 자리가 긴 경우) 데이터유실이 생길 수 있다.또한 때때로 10진수로 된 실수값을 2진수로 변환할 때 무리수로 나오는 문제가 생기게된다. ex) 0.6
실수를 다룰 때 주의할 점
이런 이유 때문에 실수를 다룰 때는 주의할 점이 있다.
- 실수 값끼리는 절대 비교 연산자로 비교하지 말아야한다.
>> 꼭 실수를 정수화 한 후에 비교할 것
double d1 = 0.6;
float f1 = 0.6f;
bResult = (d1 == f1);
System.out.println("bResult = " + bResult); // false
// 실수로 변경 or 작은 쪽으로 맞춰주기
bResult = ((int)d1 * 10 == (int)f1 * 10);
System.out.println("bResult = " + bResult); // true
bResult = ((float)d1 == f1);
System.out.println("bResult = " + bResult); // true
- 프로그램에서 실수로 산술연산은 가급적 하지 않는다.
int apple = 1;
float pieceUnit = 0.1f;
int number = 7;
// Wrong
double result = apple - number * pieceUnit; // 0.30000001192092896
// Correct
result = (apple * 10 - number ) / 10 // 0.3
- switch문에서 조건문으로 double과 float형을 넣는 것은 불가능하다.
'개발공부 > JAVA' 카테고리의 다른 글
JAVA(자바) - 난수 생성하는 3가지 방법/Seed/currentMilliSeconds (0) | 2022.07.28 |
---|---|
JAVA(자바) - Scanner로 char형 받기 (0) | 2022.07.27 |
JAVA(자바) - 다형성2(오버라이딩/동적바인딩/ super.) (0) | 2022.07.26 |
JAVA(자바) - 다형성1(업캐스팅/다운캐스팅/instanceof) (0) | 2022.07.26 |
JAVA(자바) - 상속 / 상속에서의 생산자와 super() (0) | 2022.07.26 |