문제

특정 컴퓨터에서 Mantissa 자리의 수와 단위 라운드 오프를 찾고 싶습니다. 나는 이것들이 무엇인지 이해하고 있습니다. 단지 그들을 찾는 방법을 모른다. 나는 그들이 컴퓨터마다 다를 수 있다는 것을 이해한다.

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

현재 생각하는 것은 오버플로가 발생할 때까지 숫자를 천천히 증가시키기 위해 작은 C ++ 프로그램을 작성할 수 있다는 것입니다. 그러나 어떤 유형의 숫자를 사용할지 잘 모르겠습니다.

내가 올바른 길을 가고 있습니까? 이것을 정확히 계산하는 방법은 무엇입니까?

도움이 되었습니까?

해결책

나는 당신이 사용하는 언어가 어떤 언어가 부유물이 저장되었는지를 명시 할 것이라고 생각합니다. 나는 Java가 특정 IEEE 표준 (754, 내 생각)을 사용하여이를 수행한다는 것을 알고 있습니다.

그것이 지정되지 않은 경우, 실제 숫자가 변경되는지 확인하기 위해 0.5에서 1을 추가하여 자신의 점검을 수행 할 수 있다고 생각합니다. 그렇다면 0.25 ~ 1, 0.125 ~ 1을 추가하십시오. 숫자가 변경되지 않을 때까지 다음과 같은 것입니다.

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

3 개의 Mantissa 비트 만 있으면 1 + 1/16은 1과 같습니다.

그런 다음 Mantissa 비트를 소진했습니다.

IEEE754는 처음에 암시 된 '1+'를 사용하기 때문에 실제로 기본 번호가 1이 아닌 2가 필요할 수 있습니다.

편집하다:

위에서 설명한 방법은 4 바이트 플로트가있는 시스템에 63 비트를 제공하기 때문에 몇 가지 문제가있을 수 있습니다.

그것이 중간 결과와 관련이 있는지 여부 (명백한 캐스트와 같은 코드 이후의 의심while (((float)(a + b) != (float)(a))]는 비슷한 문제가 있습니다) 또는 (가능성이 더 높음) 단위 가치가 가능할 가능성 a 분수에 더 가까운 비트로 표현할 수 있습니다 b 지수를 조정함으로써 나는 아직 모른다.

현재 IEEE754 사용과 같이 위에서 언급 한 언어 정보에 의존하는 것이 가장 좋습니다 (해당 정보를 사용할 수있는 경우).

조심스러운 선수들을위한 함정으로 문제가있는 코드를 남겨 둘 것입니다. 어쩌면 플로팅 포인트 지식을 가진 사람은 그것이 왜 이상하게 행동하는지 설명하는 메모를 남길 수 있습니다 (추측은 없습니다 :-).

편집 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로 작성된 동안 모든 언어에 적용 할 수 있어야합니다 (특히 정보를 헤더로 또는 언어 문서에 지정된 미덕으로 정보를 사용할 수없는 언어). Eclipse가 Ubuntu 상자에서 시작하는 데 너무 오래 걸리기 때문에 C에서만 테스트했습니다. :-).

다른 팁

C, 확장 C ++의 경우 정보는 다음과 같습니다. <float.h> 또는 <cfloat> 헤더.

C99의 경우 정보는 표준의 5.2.4.2.2 절에 있습니다.

  • FLT_RADIX
  • FLT_MANT_DIG
  • FLT_DIG
  • FLT_EPSILON
  • FLT_MIN_EXP
  • FLT_MIN
  • FLT_MIN_10_EXP
  • FLT_MAX_EXP
  • FLT_MAX
  • FLT_MAX_10_EXP

그리고 이들 대부분에 대한 DBL 및 LDBL 변형에 대해서도 유사하게 DBL_RADIX 또는 LDBL_RADIX). 이 표준은 IEEE 754에 적합한 값을 시사합니다 (1999 년에 현재 인 IEEE 754 표준의 이전 버전; 새로운 버전이 게시되었습니다.

체크 아웃하고 싶을 수도 있습니다 <limits> C ++ 라이브러리에서 :

#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 Mantissa 비트 수보다 더 이상 있어야합니다. 내 기계는 인쇄합니다.

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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top