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

컴파일러 최적화가 활성화된 경우 부동 소수점 반올림 코드가 다른 결과를 생성하는 이유는 무엇입니까?

Susan Sarandon
풀어 주다: 2024-11-14 19:39:02
원래의
844명이 탐색했습니다.

Why Does My Floating-Point Rounding Code Produce Different Results with Compiler Optimizations Enabled?

최적화 활성화 시 부동 소수점 반올림 차이: 컴파일러 버그 또는 최적화 딜레마?

부동 소수점 계산은 특히 다음과 같은 경우에 예상치 못한 동작을 보일 수 있습니다. 컴파일러 최적화가 활성화되었습니다. 다음 코드 조각을 고려하세요.

#include <cstdlib>
#include <iostream>
#include <cmath>

double round(double v, double digit)
{
    double pow = std::pow(10.0, digit);
    double t = v * pow;
    double r = std::floor(t + 0.5);
    return r / pow;
}

int main()
{
    std::cout << round(4.45, 1) << std::endl;
    std::cout << round(4.55, 1) << std::endl;
}
로그인 후 복사

예상 출력:

4.5
4.6
로그인 후 복사

그러나 이 코드가 최적화(O1 - O3)와 함께 g를 사용하여 컴파일되면 출력은 다음과 같습니다.

4.5
4.5
로그인 후 복사

원인 불일치:

이러한 불일치는 x86 프로세서가 내부적으로 부동 소수점 계산에 80비트 확장 정밀도를 사용한다는 사실에서 비롯됩니다. 그러나 double 변수는 일반적으로 너비가 64비트입니다. 부동 소수점 값이 CPU 레지스터에서 메모리로 저장되면 80비트 정밀도에서 64비트 정밀도로 반올림됩니다. 이 반올림으로 인해 약간의 오류가 발생할 수 있습니다.

최적화 수준의 영향:

다양한 최적화 수준은 부동 소수점 값이 메모리에 저장되는 빈도에 영향을 미칠 수 있습니다. 최적화 수준이 높을수록 이런 일이 더 자주 발생합니다. 결과적으로 반올림 오류가 더욱 두드러집니다.

해결책:

  1. -ffloat-store GCC 옵션 사용: 이 옵션은 레지스터 대신 메모리에 부동 소수점 변수를 저장하도록 컴파일러에 지시합니다. 이렇게 하면 다양한 최적화 수준에서 일관되게 반올림이 발생합니다.
  2. long double 유형 사용: long double은 일반적으로 g에서 80비트 너비입니다. 이 유형을 사용하면 반올림 문제를 완전히 피할 수 있습니다.
  3. 변수 저장소 수정: 중간 계산 결과를 변수에 저장하여 반올림 오류를 최소화합니다.

추가 고려 사항:

  • Intel x86_64 컴파일러는 기본적으로 float 및 double에 SSE 레지스터를 사용하여 확장 정밀도가 필요하지 않으므로 빌드는 이 문제의 영향을 덜 받습니다.
  • -mfpmath 컴파일러 옵션을 사용하면 x86_64 빌드에 사용되는 부동 소수점 정밀도를 제어할 수 있습니다.
  • -ffloat-store 옵션을 항상 켤지 여부는 특정 애플리케이션과 부동 소수점 정확도에 대한 민감도에 따라 다릅니다. 중요한 애플리케이션의 경우 일관된 결과를 보장하려면 이 옵션을 사용하는 것이 현명할 수 있습니다.
  • 기존 C 코드 및 라이브러리에서 잠재적인 문제를 조사하는 데는 시간이 많이 걸릴 수 있습니다. 부동 소수점 정밀도 문제를 감지하고 해결하려면 도구를 사용하거나 테스트를 구현하는 것이 좋습니다.

위 내용은 컴파일러 최적화가 활성화된 경우 부동 소수점 반올림 코드가 다른 결과를 생성하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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