2009-07-20 2 views
5

Java 코드를 C++로 포트하려고 시도했습니다. 이상한 행동을 발견했습니다. 필자는 컴파일러 옵션/fp : strict를 사용하여 Visual Studio 2008에서 부동 소수점 연산이 "올바른"것을 의미하는 경우에도 두 배의 추가 작업을 수행 할 수 없습니다.특정 Visual Studio 2008 프로젝트에서 두배가 잘못 추가되는 이유는 무엇입니까?

double a = 0.4; 
/* a: 0.40000000000000002, correct */ 

double b = 0.0 + 0.4; 
/* b: 0.40000000596046448, incorrect 
(0 + 0.4 is the same). It's not even close to correct. */ 

double c = 0; 
float f = 0.4f; 
c += f; 
/* c: 0.40000000596046448 too */ 

내가 설정 한 다른 테스트 프로젝트에서는 잘 작동합니다 (/ fp : strict는 IEEE754에 따라 동작 함).

아니요 최적화 및 FP : strict를 사용하여 Visual Studio 2008 (표준)을 사용합니다.

아이디어가 있으십니까? 정말 수레가 잘립니다? 이 프로젝트는 자바와 C++ 측면에서 모두 동일한 동작을 필요로합니다. VC++의 디버그 창에서 읽음으로써 모든 값을 얻었습니다.

해결책 : _fpreset(); // 배리 켈리의 아이디어로 해결되었습니다. 라이브러리에서 FP 정밀도를 낮게 설정했습니다.

+2

컴파일에 사용 된 정확한 명령 줄과 함께 작은 전체 테스트 프로그램을 게시 할 수 있습니까 (출력 창 등 참조)? 내가 재현 할 수있는 유일한 방법은 대신 0.0f + 0.4f를 사용하는 것입니다. –

+0

부동 소수점 형식의 부정확성을 알고 있다고 가정 할 수 있습니까? 소수점 이하 7 자리까지는 보통 기본 인쇄 정밀도가 6입니다. –

+0

@Evan이기 때문에 그의 예제는 부동 소수점 부정확도에 의해 설명되는 것 이상입니다. – Kevin

답변

8

제가 생각할 수있는 유일한 것은 아마도 제어 단어를 통해 CPU 정밀도를 수정 한 라이브러리 또는 DLL에 연결하고 있다는 것입니다.

문제가있는 계산 전에 에서 _fpreset()을 호출 해 보았습니까?

+0

그것은 그 라인을 따라 뭔가 있어야하지만 계산도 0.0 + 0.4입니까? 컴파일 시간에 평가할 수 없습니까? 디스 어셈블리를 확인하면 런타임 부동 소수점 모드에 아무 관계가 있는지 또는 컴파일 타임에 문제가 있는지 여부를 확인할 수 있습니다. –

+0

물론 가능하지만, 그렇게 간단하다면 재현하기가 쉽지 않을까요? –

+0

나는 모르겠다. 어쩌면 프로젝트에서/fp : stupid 또는 equivalent를 지정하는 것일 수도있다. 내 개인적으로 좋아하는 소스 파일을 newline - 종료되지 않습니다 따라서 프로그램이 정의되지 않은 동작을 가지고 있지만, 나는 야생에서 버그를 일으키는 것을 볼 많은 희망을 가지지 않고 있지만 ... –

3

예, 확실히 수레가 잘립니다. "정확하지 않은"경우와 마찬가지로 동일한 값의 인쇄 float f = 0.4이 표시됩니다. 시도해보십시오 :

double b = 0.0 + (double) 0.4; 

질문은 왜 그런가요? 0.0 + 0.4을 단 정밀도 표현으로 취급하는 표준에 대해서는 변명의 여지가 없습니다. 부동 소수점 리터럴은 다르게 말하면 접미어가 붙지 않는 한 배정 밀도이기 때문입니다.

무언가가 설정을 방해해야하므로 어떤 생각이 들지는 않습니다.

관련 문제