아니요, 이것은 또 다른 "왜 (1 / 3.0) * 3! = 1" 질문 이 아닙니다 .
최근에 부동 소수점에 대해 많이 읽었습니다. 특히, 동일한 계산이 다른 아키텍처 또는 최적화 설정에서 다른 결과 를 제공 할 수있는 방법 .
재생을 저장하거나 P2P 네트워크로 연결된 비디오 게임 (서버-클라이언트와 달리)의 문제로, 모든 클라이언트가 프로그램을 실행할 때마다 정확히 동일한 결과를 생성합니다-하나의 작은 불일치 부동 소수점 계산은 다른 컴퓨터에서 (또는 동일한 컴퓨터에서 ) 게임 상태가 크게 달라질 수 있습니다 !
이것은 일부 프로세서 (즉, x86)가 배 확장 정밀도를 사용하기 때문에 IEEE-754 를 "따르는"프로세서에서도 발생합니다 . 즉, 80 비트 레지스터를 사용하여 모든 계산을 수행 한 다음 64 비트 또는 32 비트로 잘라내어 계산에 64 비트 또는 32 비트를 사용하는 머신과 다른 반올림 결과를 가져옵니다.
온라인 에서이 문제에 대한 몇 가지 솔루션을 보았지만 C #이 아닌 C ++에 대한 모든 솔루션을 보았습니다.
- (Windows), (Linux?) 또는 (BSD)를
double
사용하여 배정 밀도 모드를 비활성화합니다 (모든 계산에서 IEEE-754 64 비트를 사용하도록 )._controlfp_s
_FPU_SETCW
fpsetprec
- 항상 동일한 최적화 설정으로 동일한 컴파일러를 실행하고 모든 사용자에게 동일한 CPU 아키텍처가 있어야합니다 (플랫폼 간 재생 없음). 내 "컴파일러"는 실제로 JIT이므로 프로그램이 실행될 때마다 다르게 최적화 될 수 있기 때문에 이것이 가능하지 않다고 생각합니다.
- 고정 소수점 연산, 그리고 피할 사용
float
및double
모두를.decimal
이 목적으로 작동하지만 훨씬 느려질 것이며System.Math
그것을 지원 하는 라이브러리 함수는 없습니다.
그래서 이것은 C #에서도 문제가됩니까? 모노 만 아닌 Windows 만 지원하려면 어떻게해야합니까?
그렇다면 프로그램을 정상적인 배정도로 실행하도록 강제 할 수있는 방법이 있습니까?
그렇지 않은 경우 부동 소수점 계산을 일관성있게 유지 하는 데 도움이되는 라이브러리가 있습니까?
strictfp
키워드가 있으므로 확장 된 크기가 아닌 지정된 크기 ( float
또는 double
)로 모든 계산을 수행해야합니다 . 그러나 Java는 여전히 IEE-754 지원에 많은 문제점이 있습니다. IEE-754를 잘 지원하는 프로그래밍 언어는 거의 없습니다.