2013-01-04 3 views
-1

부호없는 정수 값을 나타내는 매우 긴 이진 워드 (> 64 비트)가 있다고 가정하고 실제 수를 인쇄하려고한다고 가정 해 보겠습니다. 우리는 C++ 이야기, 그래서 당신이 부울 [] 또는 표준 : : 벡터 < 부울 > 또는 표준 : 비트 세트표준으로 끝낼 : 문자열 또는로 시작 가정하자하고 어떤 종류의 std :: ostream - 당신의 솔루션이 선호하는 것. 그러나 핵심 언어와 STL 만 사용하십시오.매우 긴 이진 표현의 정수 값 인쇄

이제 중간 크기의 결과를 얻으려면 chunkwise로 평가해야합니다. x & middot; 10 k처럼 기본 10 진수를 저장하기에 충분히 작은 중간 결과가 있어야합니다. 나는 그 지점에서 번호를 모으는 것을 알 수 있었다. 그러나 10의 밑 부분에 해당하는 청크 너비가 없기 때문에 어떻게해야할지 모르겠다. 물론, 다른 청크 너비부터 시작하여 x & middot; (2) k의 형태로 중간체를 얻은 다음 3을 기본 10으로 변환 할 수 있습니다. 그러면 x & middot가됩니다. ; 10 3 & middot; k & middot; lg2 분명히 부동 소수점 지수를 가지며 이는 도움이되지 않습니다.

어쨌든, 나는이 수학 쓰레기가 고갈되어 사려 깊은 제안에 감사하게 생각합니다.

너의 진심으로,
아르 민

+1

검색 스택 오버플로 "10 진수로 변환"또는 이와 유사합니다. 그러나 일반적으로 모든 십진수는 모든 이진수에 따라 다릅니다. –

+1

이 문제는 생각보다 훨씬 어렵습니다. 작업에 bignum 라이브러리를 사용하거나 포기한다고 말하고 싶습니다. 그렇지 않으면, 당신은 많은 수의 bidnum division과 modulo를 구현하고해야만한다. 반올림이 허용됩니까? 반올림이 허용되면 'double'로 변환하기 쉽습니다. –

+0

@MooingDuck 그렇게 힘들 수는 없지 않습니까? 전에 해봤습니까? –

답변

1

난 당신이 이미의 bignum 부문/작동하도록 모듈 기능의 일종을 가정하는거야, 그런 일을 구현하는 완전한 악몽 때문이다. 반올림은 옵션 인 경우

class bignum { 
public: 
    bignum(unsigned value=0); 
    bignum(const bignum& rhs); 
    bignum(bignum&& rhs); 
    void divide(const bignum& denominator, bignum& out_modulo); 
    explicit operator bool(); 
    explicit operator unsigned(); 
}; 

std::ostream& operator<<(std::ostream& out, bignum value) { 
    std::string backwards; 
    bignum remainder; 
    do { 
     value.divide(10, remainder); 
     backwards.push_back(unsigned(remainder)+'0'); 
    }while(value); 
    std::copy(backwards.rbegin(), backwards.rend(), std::ostream_iterator(out)); 
    return out; 
} 

, LOT 빠를 것이다,뿐만 아니라 double에 가장 bignums를 변환하는 매우 사소한해야한다. 즉, 가장 중요한 64 비트를 unsigned long에 복사하고, 그 값을 double으로 변환 한 다음, 2.0으로 곱하여 유효 비트 수에서 64를 뺍니다. (앞에 0을 생략해야하기 때문에 중요한 비트를 말합니다)
따라서 중요한 비트가 150 개인 경우 unsigned long에 상단 64를 복사하고 double으로 변환 한 다음 그 결과를 std::pow(2.0, 150-64) ~ 7.73e + 25로 곱하면됩니다. 40 개의 유효 비트가있는 경우 오른쪽에 0이 채워져 여전히 작동합니다. 40 비트를 unsigned long의 MSB에 복사하고, 그 값을 double으로 변환하고 그 값을 std::pow(2.0, 40-64) ~ 5.96e-8로 곱하면 결과를 얻을 수 있습니다!

편집

OLI 찰스 워드 내가 물 밖으로 보여 주었다 최초의 알고리즘을 불어 Double Dabble에 위키 피 디아 페이지에 대한 링크를 게시했다. 나는 바보가되지 않는다.

+0

경험으로 말하면 +1. –

+0

-1. 너는이 모든 것을 필요로하지 않는다. 물론 분열이 아닙니다. –

+0

@SethCarnegie : 경험으로 말하면서도, 그것은 위즈돈을 의미하지 않습니다. Oli Charlesworth는 나의 미친 느린 방법보다는 선형 시간에 그것을하는 방법에 대한 링크를 올렸습니다. –