2017-11-06 12 views
0

나는 기계 엡실론, C++의 다른 데이터 유형을 사용하여 1 + e > 1을 제공 가능한 가장 작은 수 e를 계산하고 싶었다. 나는 long double 행동을 설명 할 수 없다, 내가 기대 한 무엇기계 엡실론 긴 C 두 배로 ++

epsilon float: 5.96046447753906250e-008 
epsilon double: 1.11022302462515650e-016 
epsilon long double: -0.000000e+000 

floatdouble에 대한,하지만 :

여기 내 코드입니다 :

#include <cstdio> 

template<typename T> 
T machineeps() { 

    T epsilon = 1; 
    T expression; 

    do { 
    epsilon = epsilon/2; 
    expression = 1 + epsilon; 
    } while(expression > 1); 

    return epsilon; 
} 

int main() { 
    auto epsf = machineeps<float>(); 
    auto epsd = machineeps<double>(); 
    auto epsld = machineeps<long double>(); 

    std::printf("epsilon float: %22.17e\nepsilon double: %22.17e\nepsilon long double: %Le\n", epsf, epsd, epsld); 

    return 0; 
} 

그러나 나는이 이상한 출력을 얻을.

누가 잘못되었는지 말해 줄 수 있습니까?

+3

연습을 위해서입니까, 아니면 ['std :: numeric_limits :: epsilon'] (http : //en.cppreference. co.kr/w/cpp/types/numeric_limits/epsilon)? – StoryTeller

+0

재생할 수 없음 : '... 엡실론 long double : 5.421011e-20' –

+0

이 코드의 동작은 환경에 설정된 반올림 모드에 따라 다르므로, 어쨌든 꽤 깨졌습니다. –

답변

1

결과를 재현 할 수 없습니다. 내가 얻을 : 그것은 std::numeric_limits::epsilon와 유사한 값을 생성하는 내 플랫폼에

template<typename T> 
T machineeps() { 
    T epsilon = 1, prev; 
    T expression; 

    do { 

    prev = epsilon; 
    epsilon = epsilon/2; 
    expression = 1 + epsilon; 

    } while (expression > 1); 

    return prev; // <-- `1+prev` yields a result different from one 
} 

:

엡실론 긴 더블 : 뭔가처럼 5.421011e-20

를 어쨌든이, 논리적으로, 코드가 있어야한다 :

엡실론 플로트 : 1.19209289550781250e-07

,

엡실론 더블 : 2.22044604925031308e-16

엡실론 긴 더블 : 1.084202e-19

(크기의 다른 순서에주의)

0

여기에가는 몇 가지가 있습니다.

먼저 부동 소수점 변수의 실제 선언 된 유형에 관계없이 부동 소수점 연산은 가능한 최대 정밀도로 수행되는 경우가 많습니다. 따라서 예를 들어, float에 대한 산술 연산은 보통 Intel 하드웨어에서 80 비트 정밀도로 수행됩니다 (Java는 원래 이것을 금지했기 때문에 모든 부동 소수점 연산이 정확한 정밀도로 수행되어야합니다.이 살해 된 부동 소수점 성능, 그리고 그들은 그 규칙을 빨리 버렸다. 부동 소수점 계산의 결과를 저장하면 값을 적절한 유형으로 절단해야하지만, 기본적으로 대부분의 컴파일러는이를 무시합니다. 컴파일러에게이를 허용하지 말라고 말할 수 있습니다. 그 스위치는 컴파일러에 달려있다. 그렇다고해서 계산 된 결과에 의존 할 수는 없습니다. 1 + epsilon의 값이 1보다 하지 크면

둘째, 코드의 반복이 종료되므로, 반환 값 (ε)의 이하보다 참값 것이다.

셋째, 두 번째 부동 소수점 구현은 비정규 값을 처리하지 않습니다. 지수가 표현할 수있는 가장 작은 값보다 작아지면 값은 0입니다. 여기서는 long double 값을 볼 수 있습니다. IEEE 부동 소수점은 0을 갑작스럽게 처리하지 않습니다.이 최소 지수에 도달하면 값이 작아지면 점차 정밀도가 떨어집니다.가장 작은 정규화 된 값과 0 사이에는 꽤 많은 값이 있습니다.