> 백엔드 개발 > C++ > 본문

부동 소수점 결과가 컴파일러마다 최적화에 따라 다른 이유는 무엇입니까?

Susan Sarandon
풀어 주다: 2024-11-11 00:10:03
원래의
868명이 탐색했습니다.

Why Do Floating-Point Results Differ With Optimization in Different Compilers?

최적화 시 다른 부동 소수점 결과: 컴파일러 버그 또는 예상 동작?

제공된 코드 조각은 여러 컴파일러에서 최적화를 사용할 때 부동 소수점 계산 결과의 불일치를 보여줍니다. . 최적화가 없는 Visual Studio 2008 및 g에서는 코드가 예상한 출력을 생성합니다. 그러나 g 최적화를 활성화하면(O1 - O3) 잘못된 결과가 나타납니다.

Intel x86 프로세서의 내부 정밀도

이 동작의 근본 원인을 이해하려면 Intel x86 프로세서는 80비트 확장 정밀도를 사용하여 내부적으로 부동 소수점 계산을 처리합니다. 이와 대조적으로 C의 double 데이터 유형은 일반적으로 64비트 너비를 갖습니다.

최적화 및 부동 소수점 저장

최적화 수준은 CPU의 부동 소수점 값이 저장되는 빈도에 영향을 미칩니다. 메모리. 이로 인해 저장 중에 값이 80비트 정밀도에서 64비트 정밀도로 변환될 때 반올림 오류가 발생할 수 있습니다.

문제 해결

최적화 수준 전체에서 일관된 부동 소수점 결과를 보장하려면 gcc -ffloat-store 옵션을 제공합니다. 이 옵션을 사용하면 부동 소수점 값이 항상 메모리에 저장되어 레지스터 저장으로 인한 반올림 오류를 방지할 수 있습니다.

또는 gcc에서 일반적으로 너비가 80비트인 long double 데이터 유형을 사용하면, 반올림 문제를 완전히 제거할 수 있습니다.

VS2008과 g

Visual Studio가 2008에서는 확장된 부동 소수점 정밀도가 활성화된 경우에도 올바른 결과를 제공합니다. 이는 VS2008이 g와 비교하여 반올림 및 최적화를 다르게 처리한다는 것을 의미합니다.

-ffloat-store 사용: 권장 사례

-ffloat-store를 반드시 사용해야 하는 것은 아니지만, 타겟팅할 때는 권장됩니다. 최적화 수준 전체에서 예측 가능한 동작을 보장하기 위해 내부적으로 확장된 부동 소수점 정밀도를 사용하는 시스템입니다.

추가 고려 사항

x86_64 빌드의 경우 컴파일러가 기본적으로 float 및 double에 SSE 레지스터를 사용하여 확장 정밀도 사용을 제거하므로 이 문제가 발생하지 않습니다. gcc 컴파일러 옵션 -mfpmath를 사용하면 이 동작을 제어할 수 있습니다.

위 내용은 부동 소수점 결과가 컴파일러마다 최적화에 따라 다른 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿