如何在C++中实现big int

2024-02-10

我想在 C++ 中实现一个 big int 类作为编程练习——一个可以处理大于 long int 的数字的类。我知道已经有几个开源实现,但我想编写自己的实现。我正在尝试了解什么是正确的方法。

据我了解,一般策略是将数字作为字符串获取,然后将其分解为较小的数字(例如个位数),并将它们放入数组中。此时实现各种比较运算符应该是相对简单的。我主要关心的是如何实现加法和乘法之类的东西。

我正在寻找一种通用的方法和建议,而不是实际的工作代码。


一个有趣的挑战。 :)

我假设您想要任意长度的整数。我建议采用以下方法:

考虑数据类型“int”的二进制性质。考虑使用简单的二进制运算来模拟 CPU 中的电路在添加内容时所做的操作。如果您有更深入的兴趣,请考虑阅读这篇关于半加器和全加器的维基百科文章 http://en.wikipedia.org/wiki/Half_adder。你会做类似的事情,但你可以降低到如此低的水平 - 但由于懒惰,我想我会放弃并找到一个更简单的解决方案。

但在讨论有关加、减、乘的算法细节之前,让我们先了解一些数据结构。当然,一种简单的方法是将内容存储在 std::vector 中。

template< class BaseType >
class BigInt
{
typedef typename BaseType BT;
protected: std::vector< BaseType > value_;
};

您可能需要考虑是否要使向量具有固定大小以及是否要对其进行预分配。原因是,对于不同的操作,您必须遍历向量的每个元素 - O(n)。您可能想立即知道一个操作将有多复杂,而固定的 n 就可以做到这一点。

现在介绍一些对数字进行操作的算法。您可以在逻辑级别上执行此操作,但我们将使用神奇的 CPU 能力来计算结果。但我们将从 Half- 和 FullAdders 的逻辑说明中继承的是它处理进位的方式。作为示例,请考虑如何实施+= 运算符。对于 BigInt::value_ 中的每个数字,您可以将它们相加,然后查看结果是否产生某种形式的进位。我们不会按位进行操作,而是依赖于 BaseType 的性质(无论是 long、int、short 还是其他类型):它会溢出。

当然,如果你将两个数字相加,结果一定大于其中较大的一个,对吗?如果不是,则结果溢出。

template< class BaseType >
BigInt< BaseType >& BigInt< BaseType >::operator += (BigInt< BaseType > const& operand)
{
  BT count, carry = 0;
  for (count = 0; count < std::max(value_.size(), operand.value_.size(); count++)
  {
    BT op0 = count < value_.size() ? value_.at(count) : 0, 
       op1 = count < operand.value_.size() ? operand.value_.at(count) : 0;
    BT digits_result = op0 + op1 + carry;
    if (digits_result-carry < std::max(op0, op1)
    {
      BT carry_old = carry;
      carry = digits_result;
      digits_result = (op0 + op1 + carry) >> sizeof(BT)*8; // NOTE [1]
    }
    else carry = 0;
  }

  return *this;
}
// NOTE 1: I did not test this code. And I am not sure if this will work; if it does
//         not, then you must restrict BaseType to be the second biggest type 
//         available, i.e. a 32-bit int when you have a 64-bit long. Then use
//         a temporary or a cast to the mightier type and retrieve the upper bits. 
//         Or you do it bitwise. ;-)

其他算术运算类似。哎呀,你甚至可以使用 stl 函子 std::plus 和 std::minus、std::times 和 std::divides,...,但要注意进位。 :) 您还可以使用加号和减号运算符来实现乘法和除法,但这非常慢,因为这会重新计算您在每次迭代中先前调用加号和减号时已经计算出的结果。对于这个简单的任务有很多好的算法,use http://en.wikipedia.org/wiki/Multiplication_algorithm 维基百科 http://en.wikipedia.org/wiki/Division_algorithm或网络。

当然,您应该实现标准运算符,例如operator<<(只需将 value_ 中的每个值向左移动 n 位,从value_.size()-1...哦,记住携带:),operator<- 您甚至可以在这里进行一些优化,检查粗略的位数size()第一的。等等。然后通过 befriendig std::ostream 让你的类变得有用operator<<.

希望这个方法有帮助!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在C++中实现big int 的相关文章

  • 如何检查图像对象与资源中的图像对象是否相同?

    所以我试图创建一个简单的程序 只需在单击图片框中更改图片即可 我目前只使用两张图片 所以我的图片框单击事件函数的代码 看起来像这样 private void pictureBox1 Click object sender EventArgs
  • 如何使用GDB修改内存内容?

    我知道我们可以使用几个命令来访问和读取内存 例如 print p x 但是如何更改任何特定位置的内存内容 在 GDB 中调试时 最简单的是设置程序变量 参见GDB 分配 http sourceware org gdb current onl
  • 将数组向左或向右旋转一定数量的位置,复杂度为 o(n)

    我想编写一个程序 根据用户的输入 正 gt 负 include
  • 如何避免情绪低落?

    我有一个实现状态模式每个状态处理从事件队列获取的事件 根据State因此类有一个纯虚方法void handleEvent const Event 事件继承基础Event类 但每个事件都包含其可以是不同类型的数据 例如 int string
  • linux perf:如何解释和查找热点

    我尝试了linux perf https perf wiki kernel org index php Main Page今天很实用 但在解释其结果时遇到了困难 我习惯了 valgrind 的 callgrind 这当然是与基于采样的 pe
  • C++ 子字符串返回错误结果

    我有这个字符串 std string date 20121020 我正在做 std cout lt lt Date lt lt date lt lt n std cout lt lt Year lt lt date substr 0 4 l
  • 如何忽略“有符号和无符号整数表达式之间的比较”?

    谁能告诉我必须使用哪个标志才能使 gcc 忽略 有符号和无符号整数表达式之间的比较 警告消息 gcc Wno sign compare 但你确实应该修复它警告你的比较
  • 使闭包捕获的变量变得易失性

    闭包捕获的变量如何与不同线程交互 在下面的示例代码中 我想将totalEvents 声明为易失性的 但C 不允许这样做 是的 我知道这是错误的代码 这只是一个例子 private void WaitFor10Events volatile
  • 当 contains() 工作正常时,xpath 函数ends-with() 工作时出现问题

    我正在尝试获取具有以特定 id 结尾的属性的标签 like span 我想获取 id 以 国家 地区 结尾的跨度我尝试以下xpath span ends with id Country 但我得到以下异常 需要命名空间管理器或 XsltCon
  • 如何将图像和 POST 数据上传到 Azure 移动服务 ApiController 终结点?

    我正在尝试上传图片and POST表单数据 尽管理想情况下我希望它是json 到我的端点Azure 移动服务应用 我有ApiController method HttpPost Route api upload databaseId sea
  • Cython 和类的构造函数

    我对 Cython 使用默认构造函数有疑问 我的 C 类 Node 如下 Node h class Node public Node std cerr lt lt calling no arg constructor lt lt std e
  • 指针减法混乱

    当我们从另一个指针中减去一个指针时 差值不等于它们相距多少字节 而是等于它们相距多少个整数 如果指向整数 为什么这样 这个想法是你指向内存块 06 07 08 09 10 11 mem 18 24 17 53 7 14 data 如果你有i
  • vector 超出范围后不清除内存

    我遇到了以下问题 我不确定我是否错了或者它是一个非常奇怪的错误 我填充了一个巨大的字符串数组 并希望在某个点将其清除 这是一个最小的例子 include
  • 从路径中获取文件夹名称

    我有一些路c server folderName1 another name something another folder 我如何从那里提取最后一个文件夹名称 我尝试了几件事 但没有成功 我只是不想寻找最后的 然后就去休息了 Thank
  • Github Action 在运行可执行文件时卡住

    我正在尝试设置运行google tests on a C repository using Github Actions正在运行的Windows Latest 构建过程完成 但是当运行测试时 它被卡住并且不执行从生成的可执行文件Visual
  • 如何衡量两个字符串之间的相似度? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 给定两个字符串text1 and text2 public SOMEUSABLERETURNTYPE Compare string t
  • for循环中计数器变量的范围是多少?

    我在 Visual Studio 2008 中收到以下错误 Error 1 A local variable named i cannot be declared in this scope because it would give a
  • 如何将单个 char 转换为 int [重复]

    这个问题在这里已经有答案了 我有一串数字 例如 123456789 我需要提取它们中的每一个以在计算中使用它们 我当然可以通过索引访问每个字符 但是如何将其转换为 int 我研究过 atoi 但它需要一个字符串作为参数 因此 我必须将每个字
  • Qt表格小部件,删除行的按钮

    我有一个 QTableWidget 对于所有行 我将一列的 setCellWidget 设置为按钮 我想将此按钮连接到删除该行的函数 我尝试了这段代码 它不起作用 因为如果我只是单击按钮 我不会将当前行设置为按钮的行 ui gt table
  • 使用按位运算符相乘

    我想知道如何使用按位运算符将一系列二进制位相乘 但是 我有兴趣这样做来查找二进制值的十进制小数值 这是我正在尝试做的一个例子 假设 1010010 我想使用每个单独的位 以便将其计算为 1 2 1 0 2 2 1 2 3 0 2 4 虽然我

随机推荐

  • 如何在选择文本时触发事件,例如启动应用程序

    我想知道当在浏览器 消息等任何应用程序中选择文本时是否可以启动活动或应用程序 就像当我们在任何地方选择一个文本时 会出现一个小弹出窗口 提到剪切 复制 粘贴选项 我可以在那里添加另一个按钮吗 启动我的应用程序 如果可以 请指导我如何做到这一
  • 如何告诉 gzip_static 不寻找图像文件?

    我安装了 nginx 并激活了 gzip static 它适用于 CSS 和 JavaScript 文件 但它也会查找图像文件的 gzip 压缩版本 例如 png 和 gif 尽管这些文件不在要压缩的文件列表中 strace p 25044
  • 如何在 Flutter 中创建圆形 CheckBox?或者改变CheckBox的样式,比如Flutter中选中的图片?

    我想创建一个像这样的圆形复选框 我尝试过多种变体 但似乎都不起作用 包括我尝试使用 ClipRRect 由于代码较多 这里只选取部分展示 new Row children
  • 使用Spring注入EntityManager(空指针异常)[重复]

    这个问题在这里已经有答案了 这是我的 ApplicationContext xml 中的代码
  • 实体框架迁移错误 - 序列不包含元素

    command 添加迁移等等 详细 error 序列不包含元素 在出现此错误之前我做了一些事情 我对代码优先模型进行了更改 但没有运行add migration然而 然后我添加了一个 EDMX 模型来直观地发挥一个想法 我意识到 EDMX
  • Vue JS 3:如何将数据从一个组件传递到另一个组件?

    我正在尝试共享存储在变量中的数据favorite count在收藏夹组件中Favorites vue文件 我想与应用程序组件共享该数据App vue文件 但我无法 我希望如果我改变的值favorite count在收藏夹组件中 它在应用程序
  • OpenERP 6.1中创建菜单项时访问规则禁止的操作

    当我尝试创建新的菜单项以在 OpenERP 6 1 中打开窗口时 出现以下错误 访问错误 访问规则禁止的操作 或对已删除的文档执行的操作 操作 创建 文档类型 ir values 我总是可以使用绕过所有安全检查的神奇管理员帐户 但如果可能的
  • Java 小程序 --> ClassNotFound 异常

    我正在学习Java并阅读这本书 在本书中 我有一个Java applet 练习 我可以在 Eclipse 的 appletviewer 中运行它并且运行良好 但我在将小程序集成到 HTML 中时遇到问题 这是我的java代码 package
  • 如何在 Decision Manager 中导出和导入本地项目?

    我正在使用红帽决策管理器 我已经完成了我的项目 我想将其部署到另一台电脑上 我所能得到的只是一个 jar 文件 但是当我导入它时 决策管理器响应 未找到项目 希望有任何帮助 Thanks 从 Red Hat Decision Manager
  • 在类模板实例化中显式使用某些参数的默认值

    一个类模板可以有多个参数 这些参数都有默认值 template
  • 绘制两个 xts 对象

    我在用着xtsExtra绘制两个 xts 对象 考虑以下对plot xts的调用 plot xts merge a b screens c 1 2 它用于在两个单独的面板中绘制 xts 对象 a 和 b 如何控制 y 轴的间距 具体来说 我
  • 安卓蓝牙连接错误

    我在堆栈跟踪中收到以下消息 我可以找到蓝牙设备 但是当我尝试打开套接字时会发生这种情况 10 30 22 23 08 901 ERROR BTL CFG 8633 WARNING service brcm bt INQ FILTER BDA
  • 以 DirectX 编程方式创建纹理

    我试图通过提供 rgba 值数组 使用该数组创建 ID3D11Texture2D 资源 然后将其映射到我的 20 x 20 正方形 在屏幕上创建一个白色 20 x 20 像素正方形 以下是创建方形纹理和着色器资源视图的代码 void Squ
  • Intel Core 2 Duo 预取

    有人有过在 Core 2 Duo 处理器上使用预取指令的经验吗 我一直在使用 标准 预取集 prefetchnta prefetcht1等 在一系列 P4 机器上取得了成功 但是当在 Core 2 Duo 上运行代码时 似乎prefetch
  • Task.WhenAll() 和 foreach(任务中的 var task) 有什么区别

    经过几个小时的努力 我在我的应用程序中发现了一个错误 我认为下面的两个函数具有相同的行为 但事实证明它们并非如此 谁能告诉我幕后到底发生了什么 以及为什么他们的行为方式不同 public async Task MyFunction1 IEn
  • 获取 WooCommerce 中所有“库存”产品的数量

    我有一个网站 产品被视为贸易 交易 因此 当有人进行交易 购买产品 时 它就会缺货 显示当前可用产品的剩余数量 基本上是库存 的 PHP 代码片段是什么 例如 快点 仅 10 个交易 woocommerce gt 产品 可用 提前致谢 我尝
  • 在 JavaScript 中,如何检查数组是否有重复的多个值?

    很抱歉我英语说得不好 这些是我的简单代码 带有一些参数数组 if link indexOf x 1 y 2 z 3 1 link push x 1 y 2 z 3 else alert Duplicate 用于 for 循环但不提醒重复 您
  • Nodejs v0.10.x(freebsd)“X509_STORE_add_cert:证书已在哈希表中”

    我正在使用异步 Web api 并且在高于 v0 8 9 的 Nodejs 版本中遇到问题 uname a FreeBSD home 9 1 STABLE FreeBSD 9 1 STABLE 0 2 月 1 日星期五 10 38 27 E
  • 如何在 Angular 单元测试中有条件地刷新 $timeout

    我的代码是这样的 function doThing if invalidInput console error Invalid input return timeout function MyService doThing 1000 我想测
  • 如何在C++中实现big int

    我想在 C 中实现一个 big int 类作为编程练习 一个可以处理大于 long int 的数字的类 我知道已经有几个开源实现 但我想编写自己的实现 我正在尝试了解什么是正确的方法 据我了解 一般策略是将数字作为字符串获取 然后将其分解为