2016-06-22 2 views
3

편집 : 나는 유형long double그냥double이 변화를하지 않습니다 함께 일하고 있어요 것을 깨달았다. 또한 문제의 오류를 재현하는 아래 프로그램의 예제를 추가했습니다.long double에 배정 된 부동 소수점 값은 어떻게됩니까?

참고 : 저는 현재 C++ 11 및 GCC를 사용하여 컴파일하고 있습니다.

나는 결과가 아래에 두 개의 계산 사이에서 변화 상황을 처리 해요 : 위의 모든 변수는 유형 long double의이다

value1 = x * 6.0; 

double six = 6.0; 
value2 = x * six; 

value1 != value2 

.

본질적으로 실제 계산에서 6.0을 사용할 때 잘못된 대답을주는 코드 줄을 작성했습니다. 반면에, long 형 double의 변수에 6.0을 먼저 할당 한 다음 해당 변수를 계산에 사용하면 올바른 결과가 나타납니다.

나는 부동 소수점 산술의 기초를 이해하고 있으며, long double 유형에 할당 될 때 6.0의 비트에 어떤 일이 일어나고있는 것은 분명하다. 출력이

#include <iomanip> 
#include <math.h> 

long double six = 6.0; 
long double value1; 
long double value2; 

value1 = (0.7854 * (pow(10, 5)) * six * (pow(0.033, 2)) * 1.01325 * (1.27 * 11.652375/1.01325 - 1.0)); 
value2 = (0.7854 * (pow(10, 5)) * 6.0 * (pow(0.033, 2)) * 1.01325 * (1.27 * 11.652375/1.01325 - 1.0)); 

std::cout << std::setprecision(25) << value1 << std::endl; 
std::cout << std::setprecision(25) << value2 << std::endl; 

인 경우 : 내 실제 프로그램에서

샘플 (오류를 확인하는 것입니다으로 나는 계산을 왼쪽 재현됩니다) 또한

7074.327896870849993415931 
7074.327896870850054256152 

, 어떻게 부동 소수점을 이해 계산은 특정 비트 수까지만 정밀도를 유지합니다. 따라서 높은 정밀도를 설정해도 결과에 영향을 미치지 않아야합니다 (예 : 15-17 자릿수가 변경되면 숫자가 다를 경우 문제가 발생하지만 이 내 cal에 영향을 미침). culation).

질문 : 위의 두 코드 세그먼트가 (약간) 다른 결과를 생성하는 이유는 무엇입니까?

참고 : 나는 단순히==와 함께 두 숫자를 비교false을받을 수없는 경우. 방금setprecision을 사용하여 인쇄하고 각 자릿수를 확인했습니다.

+4

6.0은 이미'double' 유형 : 우리가 6.0L를 작성하여 long doubledouble에서 용어 6.0의 종류를 변경하는 경우 우리는 모두 표현은 이제 동일한 정밀도로 계산 때문에 동일한 결과를 얻을 수 있습니다. – chris

+0

@chris 의미가 있지만 차이가 나는 이유는 무엇입니까? –

+2

두 배나 플로트만으로도 '3.0 + 3.0 == 6.0' – user463035818

답변

3

여기서 제가 생각하는 문제는 프로모션 중 하나입니다.

long double six = 6.0; 
long double value1; 
long double value2; 

value1 = (0.7854 * (pow(10, 5)) * six * (pow(0.033, 2)) * 1.01325 * (1.27 * 11.652375/1.01325 - 1.0)); 
value2 = (0.7854 * (pow(10, 5)) * 6.0 * (pow(0.033, 2)) * 1.01325 * (1.27 * 11.652375/1.01325 - 1.0)); 

는 제 2 계산을 보면 우리는 더블을 입력 식의 모든 용어는 것을 알 수 있습니다.즉, 전체 식은 배 정밀도으로 평가됩니다.

그러나 첫 번째 계산에는 long double 유형의 변수 six이 포함되어 있습니다. 이로 인해 전체 식의 더 높은 정밀도로 계산됩니다..

이렇게 계산 정확도의 차이가 불일치의 원인 일 가능성이 큽니다. 첫 번째 표현식의 전체는 에서 long double까지 승격되지만 두 번째 계산은 double 정밀도로 계산됩니다.

실제로 코드를 간단하게 변경하면이를 증명할 수 있습니다.

value1 = (0.7854 * (pow(10, 5)) * six * (pow(0.033, 2)) * 1.01325 * (1.27 * 11.652375/1.01325 - 1.0)); 
value2 = (0.7854 * (pow(10, 5)) * 6.0L * (pow(0.033, 2)) * 1.01325 * (1.27 * 11.652375/1.01325 - 1.0));