【问题标题】:How to take input 128 bit unsigned integer in c++如何在 C++ 中输入 128 位无符号整数
【发布时间】:2016-10-11 21:46:19
【问题描述】:

我是 C++ 新手。我想使用 scanf 输入一个无符号的 128 位整数并使用 printf 打印它。由于我是 c++ 新手,我只知道这两种输入输出方法。有人可以帮我吗?

【问题讨论】:

  • @Walter C 中的所有内容也是 C++ 的一部分。如果您想提出更好的方法,那很好,但您的评论措辞方式不是很有帮助。
  • 你很可能在 C/C++ 中甚至没有 128 位整数类型。我认为您将需要研究是否有适合您需求的数学库。
  • 你尝试了什么?究竟是什么问题?
  • @MarkRansom 垃圾,并非 C 中的所有内容都是 C++ 的一部分。

标签: c++ 128-bit


【解决方案1】:

你可以使用 boost,但是这个库集必须自己安装:

#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;
}

【讨论】:

  • 只为 128 位整数添加 boost 合适吗?
  • @Roozbehhz 取决于需要和缺乏其他选择
  • @Roozbehhz boost 有助于解决现代 c++ 应用程序中的许多任务,因此从实用的角度来看,boost 必须成为练习程序员(包括初学者)的常用工具
  • Boost 是一把大锤子,但它是一把有用的锤子。
  • @user4581301 boost 是一套锤子。
【解决方案2】:

如果你想在没有boost的情况下相处,你可以将值存储到两个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;
    }
}

以上解决方案适用于(包括)

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

以上,有错误。

注意:pow10 可以变化,然后需要调整一些其他的常数,例如。 G。 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,最大值为

340282366920938463463374607431768211425
= ffff ffff ffff ffff ffff ffff ffff ffe1

我不知道最高数字的错误来自哪里,但可能是一些未考虑的溢出。任何建议表示赞赏,然后我会改进算法。在那之前,我会将 pow10 减少到 10 并对最高 30 个失败的数字进行特殊处理:

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

所以至少,我们可以正确处理所有有效的 128 位值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-15
    • 1970-01-01
    • 2020-07-06
    • 2019-03-26
    • 1970-01-01
    • 1970-01-01
    • 2020-01-20
    • 2012-07-12
    相关资源
    最近更新 更多