Java中double类型精度丢失的问题
PHPz
PHPz 2017-04-18 09:41:04
0
1
538

为什么使用add2方法的结果是错误的?Double.toString(d1)为什么能保持double的精度不丢失?

    public static double add(double d1, double d2) {
        BigDecimal bd1 = new BigDecimal(Double.toString(d1));
        BigDecimal bd2 = new BigDecimal(Double.toString(d2));
        return bd1.add(bd2).doubleValue();
    }
    
    public static double add2(double d1, double d2) {
        BigDecimal bd1 = new BigDecimal(d1);
        BigDecimal bd2 = new BigDecimal(d2);
        return bd1.add(bd2).doubleValue();
    }

    public static void main(String[] args) {
        double d1 = 1.0000002;
        double d2 = 0.0000002;
        System.out.println(Double.toString(d1));
        System.out.println("d1 + d2 = " + (d1 + d2)); // 1.0000003999999998
        System.out.println("d1 + d2 = " + add(d1, d2)); // 1.0000004
        System.out.println("d1 + d2 = " + add2(d1, d2)); // 1.0000003999999998
    }

PS:引出一个概念问题:

double d = XXXX.XXXXXX;
System.out.println(d);    //这里总是不会丢失精度的,为什么?
PHPz
PHPz

学习是最好的投资!

모든 응답(1)
左手右手慢动作

BigDecimal이 double을 입력 매개변수로 사용하는 경우 바이너리는 십진수를 정확하게 표현할 수 없습니다. 컴파일러는 "0.0000002" 및 "1.0000002" 문자열을 읽은 후 이를 8바이트 double 값으로 변환해야 합니다. 1.0000001999999998947288304407265968620777130126953125 .
따라서 실행 시 실제로 BigDecimal 생성자에 전달되는 실제 값은 1.0000001999999998947288304407265968620777130126953125입니다.
BigDecimal은 문자열을 입력 매개변수로 사용할 때 문자열을 매우 정확한 부동 소수점 숫자로 올바르게 변환할 수 있습니다.

System.out.println 부분에서 입력 매개변수가 string이면 직접 출력하고, 입력 매개변수가 다른 유형이면 Object.toString 메소드를 호출하여 변환한 후 출력합니다. Double.toString은 특정 정밀도를 사용하여 double을 출력하기 전에 반올림합니다.

BigDecimal 생성자에 대한 설명에서 이 문제를 다룹니다.

으아악

추가 설명:
Double.toString이 메서드는 String을 출력하고 반올림됩니다.
new BigDecimal(Double.toString(d1)) 입력 매개변수는 처리 후 String이며 BigDecimal(String val) 생성자가 호출됩니다.
소스 코드의 BigDecimal(String val) 메소드는 val을 char[] 배열로 처리합니다.

으아악

그런 다음 BigDecimal(char[] in) 생성자를 호출합니다.

그리고 새로운 BigDecimal(d1)은 BigDecimal(double val)을 호출합니다. 이 메소드가 들어온 후 가장 먼저 나오는 것은

입니다. 으아악

입력 매개변수를 바이너리로 변환하면 정확도가 떨어집니다.

이중 덧셈으로 인한 정밀도 손실은 위의 상황과 동일합니다. 먼저 비트로 변환한 후 계산한 다음 정밀도를 잃습니다. .

최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿