2009-02-02 3 views
3

특정 컴퓨터에서 가수의 수와 단위 반올림을 찾고 싶습니다. 나는 이들이 무엇인지에 대해 이해하고 있으며, 컴퓨터를 컴퓨터마다 다를 수 있다는 것을 알고 있지만 어떻게 찾을 수 있을지 전혀 모른다.특정 컴퓨터에서 가수를 찾는 방법은 무엇입니까?

오류 분석과 같은 수치 해석의 특정 측면을 수행하려면이 숫자가 필요합니다.

내가 현재 생각하고있는 것은 오버플로가 발생할 때까지 천천히 숫자를 증가시키는 작은 C++ 프로그램을 작성할 수 있지만 사용할 숫자 유형이 확실하지 않다는 것입니다.

올바른 경로에 있습니까? 이 계산 방법은 정확히 어느 정도입니까?

+0

일부 시스템에서는 일부 부동 소수점 유형 (특히 FPU가없는 시스템)을 에뮬레이션합니다. – strager

답변

5

내가 사용하고있는 언어가 무엇이든간에 플로트가 저장되는 방법을 지정한다고 생각합니다. 나는 자바가 특정 IEEE 표준 (754, 나는 생각한다)을 사용하여 이것을 수행한다는 것을 알고있다.

지정되지 않은 경우, 실제 숫자가 변경되는지 확인하기 위해 0.5를 1로 추가하여 직접 점검 할 수 있다고 생각합니다. 만약 그렇다면, 다음, 1 0.25를 추가 0.125 1 등 번호가 변경되지 않을 때까지, 뭔가 같은 :

float a = 1; 
float b = 0.5; 
int bits = 0; 
while (a + b != a) { 
    bits = bits + 1; 
    b = b/2; 
} 

만 다음 3 가수 비트, 1 + 1/16이 있다면

그런 다음 가수를 다 써 버렸습니다.

IEEE754는 처음에 묵시적 '1+'을 사용하기 때문에 실제로는 1이 아닌 2가되어야 할 수도 있습니다.

EDIT : 그것은 명확히 4 바이트 수레를 갖는 시스템에 대해 63 비트를 제공로

그것은 어떤 문제가 발생할 전술 한 방법을 보인다. 즉, 중간 결과가 어떻게 든

단위 값 a가 가까워 비트로 표현 될 수있는 가능성 (I 명시 캐스트와 같은 코드 이후 의심 [while (((float)(a + b) != (float)(a))들은 유사 문제가) 또는 (나 가능성 판단) 지수를 조정하여 분수 b에 이르기까지, 나는 아직 모른다.

지금까지 IEEE754 사용과 같은 위에서 언급 한 언어 정보에 의존하는 것이 가장 좋습니다.

문제가있는 코드는 경계하는 플레이어를위한 함정으로 남겨 둘 것입니다. 어쩌면 부동 소수점 지식을 가진 사람이 이상한 행동을하는 이유를 설명하는 메모를 남길 수 있습니다 (아무런 추측이 없습니다 :-).

EDIT 2 코드

조각이 플로트에 저장되는 중간체를 확인하여이를 해결. Jonathan Leffler가 옳았음을 알았습니다. 중간 결과였습니다.

#include <stdio.h> 
#include <float.h> 

int main(void) { 
    float a = 1; 
    float b = 0.5; 
    float c = a + b; 
    int bits = 1; 
    while (c != a) { 
     bits = bits + 1; 
     b = b/2; 
     c = a + b; 
    } 
    printf("%d\n",FLT_MANT_DIG); 
    printf("%d\n",bits); 
    return 0; 

}

이 출력 코드 (24, 24)은 계산 된 값이 헤더 파일 일치하는지 표시한다.

C로 작성되었지만 모든 언어 (특히 헤더에서 정보를 사용할 수 없거나 언어 설명서에서 지정했기 때문에)에 적용 할 수 있어야합니다.이클립스가 내 우분투 상자에서 시작될 때까지 오랜 시간이 걸리기 때문에 나는 C로만 테스트했다.

+0

초기 문제를 해결하기 위해 추가 시간을내어 주셔서 감사합니다. 귀하의 논리를 이해했으며 초기 방법이 FLT_MANT_DIG와 같은 대답을 제공하지 않는 이유에 대해 혼란스러워했습니다. –

1

C 및 확장 C++의 경우 정보는 <float.h> 또는 <cfloat> 헤더에 있습니다.

  • FLT_RADIX
  • FLT_MANT_DIG
  • FLT_DIG
  • FLT_EPSILON
  • FLT_MIN_EXP
  • FLT_MIN
  • 01 :

    C99를 들어, 정보는 표준의 섹션 5.2.4.2.2에

  • FLT_MAX_10_EXP

와 유사하게이의 대부분 DBL 및 LDBL 변화 (아무 DBL_RADIX 또는 LDBL_RADIX)에 대한

  • FLT_MAX
  • FLT_MAX_EXP
  • 23,516,
  • FLT_MIN_10_EXP
  • . 이 표준은 IEEE 754 (IEEE 754 표준의 구 버전 인 1999 년 현재 버전으로 2008 년 새 버전이 발표 되었음)에 적합한 값을 제안합니다.

    +0

    Pax가 제안한 방법을 사용하여 63의 답을 얻었지만 FLT_MANT_DIG는 가수가 23 자리임을 나타냅니다. 내가 이해하지 못하는 것이 있다고 생각하지만 왜 그 불일치가 있을까요? –

    +0

    @ Zachary, 감소 분수를 추가 할 때 1 또는 2를 기본으로 사용 했습니까? – paxdiablo

    +0

    나는 처음으로 1을 사용하여 63을 주었고, 2는 62를주었습니다. –

    1

    당신은 당신의 C++ 라이브러리의 <limits>을 확인 할 수 있습니다이 :

    #include <iostream> 
    #include <limits> 
    #include <typeinfo> 
    
    template <typename T> 
    void printDetailsFor() { 
        std::cout 
         << "Printing details for " << typeid(T).name() << ":\n" 
         << "\tradix:  " << std::numeric_limits<T>::radix  << "\n" 
         << "\tradix digits: " << std::numeric_limits<T>::digits  << "\n" 
         << "\tepsilon:  " << std::numeric_limits<T>::epsilon() << "\n" 
         << std::endl; 
    } 
    
    int main() { 
        printDetailsFor<int>(); 
        printDetailsFor<float>(); 
        printDetailsFor<double>(); 
        printDetailsFor<long double>(); 
        return 0; 
    } 
    

    난 당신이 가수 비트의 수보다 하나 더해야 std::numeric_limits<T>::digits을한다고 생각합니다. 내 시스템이 다음을 출력합니다 :

    Printing details for i: 
        radix:  2 
        radix digits: 31 
        epsilon:  0 
    
    Printing details for f: 
        radix:  2 
        radix digits: 24 
        epsilon:  1.19209e-07 
    
    Printing details for d: 
        radix:  2 
        radix digits: 53 
        epsilon:  2.22045e-16 
    
    Printing details for e: 
        radix:  2 
        radix digits: 64 
        epsilon:  1.0842e-19 
    
    관련 문제