2011-10-14 4 views
1

숫자의 표현이 다소 상대적인 측면이지만, 은 일반적으로 외부 세계에 인쇄 할 때 십진수 형식을 사용합니다.10 진수 형식의 큰 숫자 인쇄

나는 맥 OS X에있어,와의 libc의 원인을 분석하는 동안 나는 유명한 printf 기능은 약간의 기능 __ultoa를 호출 끝나는 것을 발견 - 가 vfprintf_l을 거쳐, 1104 선 __vfprintf 마지막 __ultoa. (어떤 이유로)

/* 
* Convert an unsigned long to ASCII for printf purposes, returning 
* a pointer to the first character of the string representation. 
* Octal numbers can be forced to have a leading zero; hex numbers 
* use the given digits. 
*/ 
static CHAR * 
__ultoa(u_long val, CHAR *endp, int base, int octzero, const char *xdigs) 
{ 
    CHAR *cp = endp; 
    long sval; 

    /* 
    * Handle the three cases separately, in the hope of getting 
    * better/faster code. 
    */ 
    switch (base) { 
    case 10: 
     if (val < 10) {  /* many numbers are 1 digit */ 
      *--cp = to_char(val); 
      return (cp); 
     } 
     /* 
     * On many machines, unsigned arithmetic is harder than 
     * signed arithmetic, so we do at most one unsigned mod and 
     * divide; this is sufficient to reduce the range of 
     * the incoming value to where signed arithmetic works. 
     */ 
     if (val > LONG_MAX) { 
      *--cp = to_char(val % 10); 
      sval = val/10; 
     } else 
      sval = val; 
     do { 
      *--cp = to_char(sval % 10); 
      sval /= 10; 
     } while (sval != 0); 
     break; 

    case 8: 
     do { 
      *--cp = to_char(val & 7); 
      val >>= 3; 
     } while (val); 
     if (octzero && *cp != '0') 
      *--cp = '0'; 
     break; 

    case 16: 
     do { 
      *--cp = xdigs[val & 15]; 
      val >>= 4; 
     } while (val); 
     break; 

    default:    /* oops */ 
     LIBC_ABORT("__ultoa: invalid base=%d", base); 
    } 
    return (cp); 
} 

여기 CHAR 그냥 char에 형식 정의하고 to_char가 예상했던 것과 기본적으로 을 수행합니다 : 다음과 같이 정의되어 (이 경우 모든 FreeBSD의에서 바로 온)

do { 
    *--cp = to_char(sval % 10); 
    sval /= 10; 
} while (sval != 0); 
01 :
#define to_char(n) ((n) + '0') 

진수 형태로 번역은 10 % (10)에 의해 나누어 복용하는 간단한 방법으로 발생

그러나이 작은 숫자 (최대 8 바이트)는 너무 많은 것처럼 보입니다. "수동 노동"입니다. GMP에서, 당신은 쉽게 2 5000을 계산할 수 있습니다

mpz_t n; 
mpz_init(n); 
mpz_ui_pow_ui(n, 2ul, 5000ul); 
gmp_printf("%Zd\n", n); 

을이 기지 2 (16)에 대한 쉬운 표현을 가지고 있지만, 소수점 형태는 계산하는 조금 어렵습니다.

그래서 GMP와 같은 라이브러리가 어떻게 처리 할 수 ​​있습니까? 모듈로를 사용하는 것 같고 부서가 이러한 큰 숫자에 비쌀 수 있습니다. 더 빠른 알고리즘이 있습니까? 또는 내가 틀렸고 표준 프로세스가 컴퓨터에 쉽습니다.

답변

3

표준 프로세스는 쉽지 않지만 10 진수를 얻기 위해 동등한 연산을 수행해야하는 한 가지 방법이나 다른 방법이 있습니다. 이진수의 원래 값이 단지 몇 비트이거나 단일 비트. 내 질문을 참조하십시오

How do you print the EXACT value of a floating point number?

그것은 부동 소수점에 대해,하지만 모든 큰 부동 소수점 숫자가 정수 어쨌든, 그리고 매우 대형 매우 - 작은 경우가 유일한 흥미로운 사례이다.

+0

감사합니다. R .. 정말 도움이됩니다. 주제에 대해 읽을만한 내용이 많이 있습니다. 그렇다면 나는 우주의 원자의 양을 나타내는 2의 힘을 스스로 인쇄 할 준비가되어 있을지도 모른다 :-) – sidyll