programing

이중 값을 나타내는 데 필요한 최대 문자 길이는 얼마입니까?

bestcode 2022. 9. 1. 23:17
반응형

이중 값을 나타내는 데 필요한 최대 문자 길이는 얼마입니까?

부호 없는 8비트 int를 문자열로 변환하면 결과는 항상 최대 3자(255의 경우)이며, 부호 있는 8비트 int의 경우 "-128"과 같이 4자가 필요합니다.

부동소수점 값도 마찬가지입니다."double" 또는 "float" 값을 문자열로 표현하기 위해 필요한 최대 문자 수는 몇 개입니까?

통상적인 C/C++ 더블(IEEE 754)과 통상적인 10진수 전개(즉, %e printf 포맷 없음)를 전제로 합니다.

정말 작은 숫자(0.234234)가 정말 큰 숫자(정수를 나타내는 두 개)보다 더 길지 확실하지 않습니다.

IEEE-754 사양보다 자세한 정보는 UC Berkely의 4페이지 강의 노트와 약간의 DIY 계산입니다.이 강의 슬라이드는 공학도들에게도 좋습니다.

권장 버퍼 크기

| Single| Double | Extended | Quad  |
|:-----:|:------:|:--------:|:-----:|
|   16  |  24    |    30    |  45   |

이 수치는 다음 계산에 기초하고 있습니다.

적분 부분의 최대 10진수 카운트

| Single| Double | Extended | Quad  |
|:-----:|:------:|:--------:|:-----:|
|   9   |   17   |    21    |  36   |

* Quantities listed in decimals.

10진수 카운트는 다음 공식을 기반으로 합니다.최대 천장(1 + NLog_10(2)의 소수. 여기서 N은 적분 부분*의 비트 수입니다.

최대 지수 길이

| Single| Double | Extended | Quad  |
|:-----:|:------:|:--------:|:-----:|
|   5   |   5    |     7    |   7   |
* Standard format is `e-123`.

가장 빠른 알고리즘

부동소수점 숫자를 인쇄하는 가장 빠른 알고리즘은 "부동소수점 숫자 빠르고 정확하게 인쇄" 연구 논문에 자세히 나와 있는 Grisu2 알고리즘입니다.여기서 찾을 수 있는 최고의 벤치마크를 찾을 수 있습니다.

IEEE 754-1985따르면 이중 타입으로 표시되는 값의 가장 긴 표기법.

-2.2250738585072020E-308

는 24글자입니다.

헤더 " " "<float.h> C, 에서의<cfloat>C++에는 범위 및 부동소수점 유형의 기타 메트릭과 관련된 여러 상수가 포함되어 있습니다. 중 가 '아예'입니다.DBL_MAX_10_EXP '10'을 double since. 터터가래1eN「」가 필요합니다.N+1수 은 '네거티브'입니다.그러면 답은 다음과 같습니다.

int max_digits = DBL_MAX_10_EXP + 2;

이는 지수가 가능한 가장 큰 가수 값을 나타내기 위해 필요한 자릿수보다 큰 것으로 가정합니다.그렇지 않으면 소수점 뒤에 더 많은 자릿수가 이어집니다.

수정

가장 긴 숫자는 실제로 가장 작은 음수입니다.지수와 가수 모두를 커버하기에 충분한 자릿수가 필요합니다.은 " " " 입니다.-pow(2, DBL_MIN_EXP - DBL_MANT_DIG)서, snowledge.DBL_MIN_EXP유도통해 .-pow(2,-N)「」가 필요합니다.3+N표현 (비과학적인 10진수 표현 문자)"-0."그에 , , 음음음음음 , ,N이치노 정답은 ★★★★★★★★★★★★★★★★★★★★.

int max_digits = 3 + DBL_MANT_DIG - DBL_MIN_EXP

64비트 IEEE 더블의 경우,

DBL_MANT_DIG = 53
DBL_MIN_EXP = -1023
max_digits = 3 + 53 - (-1023) = 1079

"이중 값을 나타내는 데 필요한 최대 문자 길이는 얼마입니까?"

이 질문에 대한 정확한 답변은 다음과 같습니다. 8개의 ASCII 문자 - 16진수 형식, '0x' 접두사 - 100% 정확도 : 제외). (단, 단순한 농담은 아닙니다.)

IEEE-754 의 사용 가능한 정밀도는 약 16 자리수의 소수점 이하입니다.따라서, 교육 목적을 제외하고, 그 이상의 표현은 자원이나 컴퓨팅 능력의 낭비일 뿐입니다.

  • 사용자는 스크리인에 700자리 숫자가 표시되어도 더 많은 정보를 얻을 수 없습니다.

  • 이 "더 정확한" 형식으로 저장된 구성 변수는 무용지물입니다. 이 숫자를 조작할 때마다 정확도가 저하됩니다.(사인 비트 변경 제외)

만약 누군가가 더 정확한 정밀도를 필요로 한다면, 대략 18자리의 정확도를 가진 80비트 길이의 더블이나 f.libquadmath 같은 것이 있습니다.

안부 전해요.

"정확히 325자가 필요합니다."

보아하니 (이것은 매우 일반적인 경우입니다)여러 숫자 베이스 간의 변환 방법을 이해하지 못하고 있는 것 같습니다.

DBL_MIN의 정의는 아무리 정확해도 하드웨어 정밀도에 의해 제한됩니다.하드웨어 정밀도는 보통 80비트 또는 18자리까지입니다(x86 및 이와 유사한 아키텍처).

이러한 이유로 f.gmp 또는 mpfr과 같은 특수한 임의 정밀도 산술 라이브러리가 발명되었다.

1024로는 충분하지 않습니다.가장 작은 음의 두 배 값은 1077자리 소수입니다.여기 자바 코드가 있습니다.

double x = Double.longBitsToDouble(0x8000000000000001L);
BigDecimal bd = new BigDecimal(x);
String s = bd.toPlainString();
System.out.println(s.length());
System.out.println(s);

다음은 프로그램의 결과입니다.

1077
-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004940656458412465441765687928682213723650598026143247644255856825006755072702087518652998363616359923797965646954457177309266567103559397963987747960107818781263007131903114045278458171678489821036887186360569987307230500063874091535649843873124733972731696151400317153853980741262385655911710266585566867681870395603106249319452715914924553293054565444011274801297099995419319894090804165633245247571478690147267801593552386115501348035264934720193790268107107491703332226844753335720832431936092382893458368060106011506169809753078342277318329247904982524730776375927247874656084778203734469699533647017972677717585125660551199131504891101451037862738167250955837389733598993664809941164205702637090279242767544565229087538682506419718265533447265625

float/double을 문자열로 변환할 때 정밀도를 설정하여 문자열 표현의 자리 수를 제어할 수 있습니다. 자리수는 .std::numeric_limits<double>::max()지정한 정밀도에 맞춰야 합니다.

#include <iostream>
#include <limits>
#include <sstream>
#include <iomanip>

int main()
{
 double x = std::numeric_limits<double>::max();

 std::stringstream ss;
 ss << std::setprecision(10) << std::fixed << x;

 std::string double_as_string = ss.str();
 std::cout << double_as_string.length() << std::endl;
}

1개의 자리수 중 많은 , 즉, 「」, 「」, 「」, 「」의 자리수가 가장 많은 입니다.double10월 320일

몇 글자가 필요한지 확인하는 데 사용할 수 있습니다. snprintf()전달된 문자를 인쇄하는 데 필요한 문자 수를 반환합니다.

/* NOT TESTED */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
    char dummy[1];
    double value = 42.000042; /* or anything else */
    int siz;
    char *representation;
    siz = snprintf(dummy, sizeof dummy, "%f", value);
    printf("exact length needed to represent 'value' "
           "(without the '\\0' terminator) is %d.\n", siz);
    representation = malloc(siz + 1);
    if (representation) {
        sprintf(representation, "%f", value);
        /* use `representation` */
        free(representation);
    } else {
        /* no memory */
    }
    return 0;
}

주의:snprintf()C99 9999 C99 。C89 컴파일러가 확장으로 제공하는 경우 위의 프로그램이 예상한 대로 작동하지 않을 수 있습니다.

편집: 링크를 다음으로 변경했습니다.snprintf()C99 표준에 의해 부과된 기능을 실제로 기술하는 것으로, 원래의 링크에 기재되어 있는 설명이 잘못되어 있습니다.
2013년 : 1차 편집 사이트보다 제가 선호하는 POSIX 사이트로 링크를 다시 변경하였습니다.

'대표'가 무슨 뜻인지에 따라 다르죠소수점에는 정확한 부동 소수점 표현이 없습니다.십진수 -> 이진수 -> 십진수를 변환할 때 정확한 십진수 표현은 없으며 이진수 표현 끝에 노이즈 비트가 있습니다.

이 질문은 10진수부터 시작하는 것이 아니라 모든 소스 코드(및 사용자 입력 필요)가 10진수이며 잘라내기 문제가 있을 수 있습니다.이런 상황에서 '정확한'이란 무슨 뜻일까요?

기본적으로 부동소수점 표현에 따라 달라집니다.

48비트의 사마귀가 있는 경우 소수점 이하 16자리입니다.지수는 나머지 14비트(약 10진수 5자리)일 수 있습니다.

경험의 법칙은 비트 수가 십진수의 약 3배라는 것입니다.

의 소수점 한 최대 수.double 예 : 예 )"%f"은 ㄴㄴ)ㄹ 수 있다.의 값을 .-DBL_MIN IEEE (파일명: -0x1p-1022 (binary64 IEEE 754))double를 입력하려면 , 정확하게 325 문자가 필요합니다.이겁니다.DBL_DIG + abs(DBL_MIN_10_EXP) + strlen("-0.")이건 당연히...log10(fabs(DBL_MIN))는 308이며, 이 또한 308 입니다.abs(DBL_MIN_10_EXP)+1에), (+1은 0이 될 수 있습니다.

int lz;                 /* aka abs(DBL_MIN_10_EXP)+1 */
int dplaces;
int sigdig;             /* aka DBL_DECIMAL_DIG - 1 */
double dbl = -DBL_MIN;

lz = abs((int) lrint(floor(log10(fabs(dbl)))));
sigdig = lrint(ceil(DBL_MANT_DIG * log10((double) FLT_RADIX)));
dplaces = sigdig + lz - 1;
printf("f = %.*f\n", dplaces, dbl);

Greg A에 근거인정된 답변의 개선점. Woods의 정확한 코멘트, 더 보수적이지만 여전히 적절한 수의 캐릭터가 필요합니다.3 + DBL_DIG + -DBL_MIN_10_EXP(합계 325)는 필요할 수 있는 선두 "-0"에 대해 3이 됩니다.문자열을 하는 경우null에 1을 합니다(C는 null 1).'\0' 사이즈의 버퍼 326)가될 수 과 같이 종료합니다. ( 「 326 」 。

#include <limits.h>

char buffer[4 + DBL_DIG + -DBL_MIN_10_EXP];

다음과 같은 C++ 수치 제한 인터페이스를 원하는 경우:

#include <limits>

char buffer[4 + std::numeric_limits<double>::digits10 + -std::numeric_limits<double>::min_exponent10];

언급URL : https://stackoverflow.com/questions/1701055/what-is-the-maximum-length-in-chars-needed-to-represent-any-double-value

반응형