저는 C++을 처음 사용합니다. scanf를 사용하여 부호없는 128 비트 정수를 입력 받아 printf를 사용하여 인쇄하려고합니다. 내가 C++을 처음 접했을 때, 나는이 두 가지 입력 방법을 알고있다. 누군가 나를 도울 수 있습니까?C++에서 128 비트 부호없는 정수 입력 방법
2
A
답변
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
당신이 함께 부스트없이 얻고 싶은 경우에, 당신은 다음과 같은 두 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 비트 값을 처리 할 수 있습니다.
@Walter C의 모든 것은 C++의 일부입니다. 더 나은 방법을 제안하고 싶다면 의견을 말한 방식은별로 도움이되지 않습니다. –
C/C++에서 128 비트 정수형조차 갖고 있지 않은 경우도 있습니다. 여러분의 필요에 맞는 수학 라이브러리가 있는지 살펴볼 필요가 있다고 생각합니다. –
당신은 무엇을 시도 했습니까? 그 질문은 정확히 무엇입니까? – Walter