제공된 코드 조각은 여러 컴파일러에서 최적화를 사용할 때 부동 소수점 계산 결과의 불일치를 보여줍니다. . 최적화가 없는 Visual Studio 2008 및 g에서는 코드가 예상한 출력을 생성합니다. 그러나 g 최적화를 활성화하면(O1 - O3) 잘못된 결과가 나타납니다.
이 동작의 근본 원인을 이해하려면 Intel x86 프로세서는 80비트 확장 정밀도를 사용하여 내부적으로 부동 소수점 계산을 처리합니다. 이와 대조적으로 C의 double 데이터 유형은 일반적으로 64비트 너비를 갖습니다.
최적화 수준은 CPU의 부동 소수점 값이 저장되는 빈도에 영향을 미칩니다. 메모리. 이로 인해 저장 중에 값이 80비트 정밀도에서 64비트 정밀도로 변환될 때 반올림 오류가 발생할 수 있습니다.
최적화 수준 전체에서 일관된 부동 소수점 결과를 보장하려면 gcc -ffloat-store 옵션을 제공합니다. 이 옵션을 사용하면 부동 소수점 값이 항상 메모리에 저장되어 레지스터 저장으로 인한 반올림 오류를 방지할 수 있습니다.
또는 gcc에서 일반적으로 너비가 80비트인 long double 데이터 유형을 사용하면, 반올림 문제를 완전히 제거할 수 있습니다.
Visual Studio가 2008에서는 확장된 부동 소수점 정밀도가 활성화된 경우에도 올바른 결과를 제공합니다. 이는 VS2008이 g와 비교하여 반올림 및 최적화를 다르게 처리한다는 것을 의미합니다.
-ffloat-store를 반드시 사용해야 하는 것은 아니지만, 타겟팅할 때는 권장됩니다. 최적화 수준 전체에서 예측 가능한 동작을 보장하기 위해 내부적으로 확장된 부동 소수점 정밀도를 사용하는 시스템입니다.
x86_64 빌드의 경우 컴파일러가 기본적으로 float 및 double에 SSE 레지스터를 사용하여 확장 정밀도 사용을 제거하므로 이 문제가 발생하지 않습니다. gcc 컴파일러 옵션 -mfpmath를 사용하면 이 동작을 제어할 수 있습니다.
위 내용은 부동 소수점 결과가 컴파일러마다 최적화에 따라 다른 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!