IT박스

JVM에서 부동 소수점 연산이 모든 플랫폼에서 동일한 결과를 제공합니까?

itboxs 2020. 12. 25. 09:06
반응형

JVM에서 부동 소수점 연산이 모든 플랫폼에서 동일한 결과를 제공합니까?


여러 컴퓨터에서 실행되는 응용 프로그램에서 Java를 사용하고 있으며 모든 컴퓨터에서 수학 연산에 대해 동일한 결과를 얻어야합니다. Java의 부동 소수점 프리미티브를 사용하는 것이 안전합니까? 아니면 고정 소수점 수학 라이브러리를 사용해야합니까?


일반적으로 아닙니다. 그러나 strictfp표현식 을 사용할 수 있습니다 .

FP-strict 표현식 내에서 모든 중간 값은 float 값 세트 또는 double 값 세트의 요소 여야합니다. 즉, 모든 FP-strict 표현식의 결과는 단일 및 이중 형식을 사용하여 표현 된 피연산자에 대한 IEEE 754 산술에 의해 예측 된 결과 여야 함을 의미합니다. .

FP에 엄격하지 않은 표현식 내에서 구현시 확장 된 지수 범위를 사용하여 중간 결과를 나타낼 수있는 여유가 있습니다. 대략적으로 말하면, 부동 값 세트 또는 이중 값 세트를 독점적으로 사용하면 오버 플로우 또는 언더 플로우가 발생할 수있는 상황에서 계산이 "정답"을 생성 할 수 있다는 것입니다.


뿐만 아니라 strictfp, 또한 거기에 StrictMath결과가 초월 및 기타 기능에 대한 예측 가능해야한다.


JVM은 IEEE 사양을 일관되게 구현해야하며이 사양은 매우 기술적이고 정확합니다. 부동 소수점은 부동의 프리미티브 두 번 있는 모든 플랫폼에서 동일.

차이점은 중간 결과의 처리에만 있으며 가상 머신 구현은 동일한 실행 프레임 내에서 로컬을 포함하는 표현식을 평가하는 동안 부동 확장 지수 및 이중 확장 지수 형식을 사용할 수 있습니다.

따라서 다음과 같은 코드가있는 경우 :

double d1 = 0.342;
double d2 = 1.328479;
double d3 = 4.99384728796;
System.out.println(d1 * d2 / d3);

이것은 strictfp 컨텍스트가 아니며 런타임에 다른 JVM간에 차이가있을 수 있습니다. 이는 표현식 d1 * d2 / d3의 평가에서 d1 * d2의 중간 결과가 "중간 결과"/ d3 표현식에 사용되고 JVM이 float-extended-exponent 및 double-extended-exponent 형식을 사용할 수 있기 때문입니다. "중간 결과"를 저장합니다.

이 문제를 해결하려면 다른 사람들이 여기에 답변 한대로 strictfp 또는 StrictMath를 사용하거나 표현식에서 중간 결과를 사용하지 마십시오. 이를 수행하는 한 가지 방법은 중간 결과를 힙에 저장하는 것입니다. 예를 들면 다음과 같습니다.

class MyClass {
    static double d1 = 0.342;
    static double d2 = 1.328479;
    static double d3 = 4.99384728796;
    static double intermediate_result = 0d;
    public static void main(String[] args) {
        intermediate_result = d1 * d2;
        System.out.println(intermediate_result / d3);
    }
}

참조 URL : https://stackoverflow.com/questions/22335046/will-floating-point-operations-on-the-jvm-give-the-same-results-on-all-platforms

반응형