2016-06-10 3 views
2

저는 C++을 처음 사용합니다. scanf를 사용하여 부호없는 128 비트 정수를 입력 받아 printf를 사용하여 인쇄하려고합니다. 내가 C++을 처음 접했을 때, 나는이 두 가지 입력 방법을 알고있다. 누군가 나를 도울 수 있습니까?C++에서 128 비트 부호없는 정수 입력 방법

+1

@Walter C의 모든 것은 C++의 일부입니다. 더 나은 방법을 제안하고 싶다면 의견을 말한 방식은별로 도움이되지 않습니다. –

+1

C/C++에서 128 비트 정수형조차 갖고 있지 않은 경우도 있습니다. 여러분의 필요에 맞는 수학 라이브러리가 있는지 살펴볼 필요가 있다고 생각합니다. –

+1

당신은 무엇을 시도 했습니까? 그 질문은 정확히 무엇입니까? – Walter

답변

3

당신은 부스트를 사용할 수 있지만이 라이브러리 세트를 직접 설치해야합니다

#include <boost/multiprecision/cpp_int.hpp> 
#include <iostream> 

int main() 
{ 
    using namespace boost::multiprecision; 

    uint128_t v = 0; 

    std::cin >> v; // read 
    std::cout << v << std::endl; // write 

    return 0; 
} 
+0

은 적절한 128 비트 정수에만 부스트를 추가합니까? –

+0

@Roozbehhz는 다른 옵션의 필요성과 부족함에 달려 있습니다 – vu1p3n0x

+0

@Roozbehhz boost는 최신 C++ 응용 프로그램에서 많은 작업을 해결하는 데 도움이되므로 실용적인 관점에서 보면 초보자를 포함한 프로그래머를위한 일반적인 도구가되어야합니다. – AnatolyS

0

당신이 함께 부스트없이 얻고 싶은 경우에, 당신은 다음과 같은 두 uint64_t에 값을 저장 할 수 있습니다

std::string input; 
std::cin >> input; 

uint64_t high = 0, low = 0, tmp; 
for(char c : input) 
{ 
    high *= 10; 
    tmp = low * 10; 
    if(tmp/10 != low) 
    { 
     high += ((low >> 32) * 10 + ((low & 0xf) * 10 >> 32)) >> 32; 
    } 
    low = tmp; 
    tmp = low + c - '0'; 
    high += tmp < low; 
    low = tmp; 
} 

인쇄 한 후, 그러나, 더 추한 가져옵니다

std::vector<uint64_t> v; 
while(high | low) 
{ 
    uint64_t const pow10 = 100000000; 
    uint64_t const mod = (((uint64_t)1 << 32) % pow10) * (((uint64_t)1 << 32) % pow10) % pow10; 
    tmp = high % pow10; 
    uint64_t temp = tmp * mod % pow10 + low % pow10; 
    v.push_back((tmp * mod + low) % pow10); 
    low = low/pow10 + tmp * 184467440737 + tmp * /*0*/9551616/pow10 + (temp >= pow10); 
    high /= pow10; 
} 
std::vector<uint64_t>::reverse_iterator i = v.rbegin(); 
while(i != v.rend() && *i == 0) 
{ 
    ++i; 
} 
if(i == v.rend()) 
{ 
    std::cout << 0; 
} 
else 
{ 
    std::cout << *i << std::setfill('0'); 
    for(++i; i != v.rend(); ++i) 
    { 
     std::cout << std::setw(8) << *i; 
    } 
} 

bove 솔루션이 작동합니다 (포함)

340282366920938463463374516198409551615 
= 0x ffff ffff ffff ffff ffff ad06 1410 beff 

위와 같은 오류가 있습니다.

주 : pow10은 변경 될 수 있으며, 다른 일부 상수는 조정될 필요가 있습니다. 지. pow10 = 10 :

low = low/pow10 + tmp * 1844674407370955161 + tmp * 6/pow10 + (temp >= pow10); 

및 인쇄 여전히 제대로 작동하는 최대 수를 줄일 수 감소의 결과를 증가

std::cout << std::setw(1) << *i; // setw also can be dropped in this case 

최대를 발생시킵니다. pow10으로 = 10, 최대, 아마도 일부 unconsidered 오버플로 매우 높은 수치의 오류가 어디에서 오는지 모르겠어요

340282366920938463463374607431768211425 
= ffff ffff ffff ffff ffff ffff ffff ffe1 

입니다, 아직. 어떤 제안이라도 고맙게 여기면 알고리즘을 개선 할 것입니다. 그 때까지 나는 10 pow10을 줄일 것 가장 높은 30 개 실패 숫자에 대한 특별한 취급을 소개 :

std::string const specialValues[0] = { /*...*/ }; 
if(high == 0xffffffffffffffff && low > 0xffffffffffffffe1) 
{ 
    std::cout << specialValues[low - 0xffffffffffffffe2]; 
} 
else 
{ 
    /* ... */ 
} 

그래서 적어도, 우리는 정확하게 모든 유효한 128 비트 값을 처리 할 수 ​​있습니다.