특정 기계에서 Mantissa 길이를 찾는 방법은 무엇입니까?
-
20-08-2019 - |
문제
특정 컴퓨터에서 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