5

코드 :Java float가 double보다 정확합니까?

class Main { 
    public static void main (String[] args) { 
     System.out.print("float: "); 
     System.out.println(1.35f-0.00026f); 
     System.out.print("double: "); 
     System.out.println(1.35-0.00026); 
    } 
} 

출력 :

float: 1.34974 
double: 1.3497400000000002 

??? float가 올바른 답을 얻었으나 double은 아무 곳에서나 여분의 물건을 추가합니다. 왜?

double이 float보다 정확하지 않습니까?

+2

시도이 **에서 System.out.println (". % 20F"및 String.format (1.35f-0.00026f)); ** – lummycoder

답변

8

float는 4 바이트이고 double은 8 바이트입니다. 확인 What Every Computer Scientist Should Know About Floating-Point Arithmetic

는 확실히 더블은 약간 덜 오류를 반올림 한, 그래서 더 정밀도를 가지고있다.

제한된 수의 비트로 무한히 많은 실수를 압축합니다. 에는 대략적인 표현이 필요합니다. 무한히 많은 수의 정수가 있지만 대부분의 프로그램에서 정수 계산의 결과는 32 비트로 저장 될 수 있습니다. 반대로 고정 된 숫자의 비트가 주어진 경우 대부분의 실수로 계산하면 을 해당 비트를 사용하여 정확히 표현할 수없는 양이 생성됩니다. 따라서 부동 소수점 계산의 결과는 종종 순서로 반올림하여 해당 유한 표현에 적합해야합니다.이 반올림 오류는 부동 소수점 계산의 특징 인 입니다. 보조 노트에

: -

당신이 규칙에 대해 뭔가를 알고 있다면 정확한 진수 값은 다음 더블 값을 변환 java.math.BigDecimal

2

를 사용하려는 경우 내가 제안 ~ (에 대한 설명서에서 지정) Double.toString [Java-API]를 사용하면 double 값 을 가장 가까운 이웃과 구별하기에 충분한 최소 소수점을 인쇄하고 소수점 이하 전후의 적어도 하나의 숫자를 인쇄합니다.

확인 조슈아 블로흐의 자바 퍼즐 러 (Puzzler) : 트랩,주의 할 점, 그리고 코너 케이스 - 퍼즐 2 : 변화를위한 시간. 그는이 장을이 장에서 설명합니다.

3

이 이유는 부동 소수점 계산이있는 숫자의 메커니즘입니다. 또한 java가 float 값을 인쇄하려고하면 후행 0을 자릅니다. 그리고 double 유형은 8 바이트를 사용하며 float은 4를 사용합니다. 따라서 double의 크기가 더 큽니다.

그래서 자바가 float 값을 계산할 때, 1.3497400과 같은 것을 얻고 출력 전에 잘라냅니다. 그리고 자바가 double 값을 계산할 때 더 많은 자리수를 얻으므로 그 결과를 얻습니다.

에 한번 더 나은 이해를 위해 간단한 예제를 실행 :

public class Test { 
    public static void main(String[] args) { 
     float sum = 0; 
     for (int i = 1; i <= 10; i++) { 
      sum += 0.1; 
     } 
     System.out.println(sum); 
    } 
} 

public class Test { 
    public static void main(String[] args) { 
     double sum = 0; 
     for (int i = 1; i <= 10; i++) { 
      sum += 0.1; 
     } 
     System.out.println(sum); 
    } 
}