정밀도를 잃지 않고 IEEE 754 이중 유형으로 저장할 수있는 가장 큰 "부동없는"정수는 무엇입니까?
정밀도를 잃지 않고 IEEE 754 이중 유형으로 저장할 수있는 가장 큰 "부동없는"정수는 무엇입니까?
답변:
정밀도를 잃지 않고 double에 저장할 수있는 가장 큰 / 가장 큰 정수는 가능한 가장 큰 double 값과 같습니다. 즉, DBL_MAX
약 1.8 × 10 308 (더블이 IEEE 754 64 비트 더블 인 경우). 정수입니다. 정확하게 표현되었습니다. 무엇을 더 원하십니까?
계속해서 가장 큰 정수가 무엇인지 물어보십시오 . 정밀도를 잃지 않고 모든 작은 정수 를 IEEE 64 비트 복식에 저장할 수 있습니다. IEEE 64 비트 double에는 52 비트 가수가 있으므로 2 53 이라고 생각합니다 .
또는 그것을 보는 또 다른 방법 : 일단 바이어스가 지수에서 제거되고 질문과 관련이없는 부호 비트를 무시하면 double로 저장된 값은 2의 거듭 제곱에 52의 정수에 2를 곱한 값입니다 지수-52 . 따라서 지수 52를 사용하면 2 52 에서 2 53 − 1 까지의 모든 값을 저장할 수 있습니다 . 그런 다음 지수 53을 사용하면 2 53 이후에 저장할 수있는 다음 숫자 는 2 53 + 1 × 2 53 − 52 입니다. 따라서 정밀도 손실은 2 53 + 1에서 처음 발생합니다 .
9007199254740992 (즉 9,007,199,254,740,992) :)
프로그램
#include <math.h>
#include <stdio.h>
int main(void) {
double dbl = 0; /* I started with 9007199254000000, a little less than 2^53 */
while (dbl + 1 != dbl) dbl++;
printf("%.0f\n", dbl - 1);
printf("%.0f\n", dbl);
printf("%.0f\n", dbl + 1);
return 0;
}
결과
9007199254740991 9007199254740992 9007199254740992
double dbl = 1; while (dbl + 1 != dbl) dbl *= 2; while (dbl == --dbl);
동일한 결과를 산출합니다
while (dbl == --dbl)
영원히 반복되거나 전혀 반복되지 않습니다. :) (이 경우 2 ^ N이므로 전혀 아님). 아래에서 접근해야합니다. 또한 while 루프가 dbl을 감소시키기 때문에 한 번의 검사로 인해 예상 결과보다 1이 적습니다. 그리고 왼쪽을 평가하기 전후에 (내가 아는 한 정의되지 않은) 감소가 이루어지면 실행 순서에 달려 있습니다. 전자 인 경우 항상 사실이며 영원히 반복됩니다.
while (dbl + 1 != dbl) dbl++;
에 대한 약점은 수학을 고려 dbl + 1 != dbl
하여 평가할 수 있습니다 . 이것은 무한 루프로 끝날 수 있습니다. long double
FLT_EVAL_METHOD == 2
Wikipedia는 IEEE 754에 대한 링크와 동일한 컨텍스트에서 다음과 같이 말합니다 .
일반적인 컴퓨터 시스템에서 '배정도'(64 비트) 이진 부동 소수점 수의 계수는 53 비트 (이 중 하나는 암시적임), 지수는 11 비트 및 하나의 부호 비트입니다.
2 ^ 53은 9 * 10 ^ 15 이상입니다.
IEEE 754 double (64 비트)로 표시 될 수있는 가장 큰 정수는 값 자체가 정수이므로 유형이 나타낼 수있는 가장 큰 값과 동일합니다.
이것은로 구성되며 다음과 같이 0x7FEFFFFFFFFFFFFF
구성됩니다.
0x7FE
(바이어스를 뺀 후 1023을 나타내는 2046) 0x7FF
(2047은 a NaN
또는 무한대 를 나타냄 )가 아닙니다 .0xFFFFFFFFFFFFF
는 모두 52 비트입니다.이진수에서 값은 암시 적 1과 가수에서 다른 52 개의 1이오고 지수에서 971 개의 0 (1023-52 = 971)이됩니다.
정확한 소수점 값은 다음과 같습니다.
1797693134862315708145274237317043567980705675258449965989174768031572607800285387605895586327668781715404589535143824642343213268894641827684675467035375169860499105765512820762454900903893289440758685084551339423045832369032229481658013493321233124857979
이것은 대략 1.8 x 10 308 입니다.
가수의 크기를 봐야합니다. IEEE 754 64 비트 부동 소수점 숫자 (52 비트 및 1을 암시 함)는 2 ^ 53 이하의 절대 값을 갖는 정수를 정확하게 나타낼 수 있습니다.
1.7976931348623157 × 10 ^ 308
http://en.wikipedia.org/wiki/Double_precision_floating-point_format
DECIMAL_DIG
에서가 <float.h>
그 적어도 합리적인 근사치를 제공해야합니다. 십진수를 다루고 실제로 이진으로 저장되므로 정밀도를 잃지 않고 조금 더 큰 것을 저장할 수는 있지만 정확히 말하기가 얼마나 어렵습니다. FLT_RADIX
와 에서 알아낼 수 있어야한다고 생각 DBL_MANT_DIG
하지만 결과를 완전히 신뢰할 수는 없습니다.
double
a가 특정 IEEE 유형에 직접 대응하지만 필수는 아니며,이 답변이 작성되었을 때 특정 IEEE 유형도 언급하지 않았다는 잘못된 가정을 기반으로 합니다.