C/C++高精度运算(大整数运算)详细讲解

yizhihongxing

C/C++高精度运算(大整数运算)详细讲解

简介

在进行高精度运算时,我们需要使用到很大的整数进行计算,如:1000的阶乘,1到1000的和等。而C/C++默认的整型数据类型一般只能存储到2^32-12^64-1这样的范围,需要我们使用数组或链表等结构来存储这类大数。本篇文章将详细介绍如何使用C/C++实现大整数和高精度运算。

实现方式

在C/C++中,大整数可以使用数组或链表来存储。我们通常使用数组来存储,每一位数字对应数组中的一个元素,最高位在数组的最前面。在进行高精度运算的过程中,需要注意进位和补零等情况。

加法

我们通常采用逐位相加的方法进行高精度加法。依次计算每一位的和,并且考虑到进位情况。

以下是C++代码示例:

vector<int> add(vector<int> a, vector<int> b) {
    vector<int> c;
    int t = 0; //进位
    for (int i = 0; i < a.size() || i < b.size() || t; i++) {
        if (i < a.size()) t += a[i];
        if (i < b.size()) t += b[i];
        c.push_back(t % 10); //将当前位数字存入结果数组中
        t /= 10; //更新进位状态
    }
    return c;
}

其中,vector是标准库中的动态数组容器,可变长数组,可以通过push_back方法在末尾添加元素。

减法

我们通常采用逐位相减的方法进行高精度减法。依次计算每一位的差,并且考虑借位情况。

以下是C++代码示例:

vector<int> sub(vector<int> a, vector<int> b) {
    vector<int> c;
    int t = 0; //借位
    for (int i = 0; i < a.size(); i++) {
        t = a[i] - t;
        if (i < b.size()) t -= b[i];
        c.push_back((t + 10) % 10); //将当前位数字存入结果数组中
        if (t < 0) t = 1; else t = 0; //更新借位状态
    }
    while (c.size() > 1 && c.back() == 0) c.pop_back(); //删除前导零
    return c;
}

乘法

我们采用逐位相乘的方法进行高精度乘法。将一个数的每一位都分别与另一个数相乘,再将结果相加即可。

以下是C++代码示例:

vector<int> mul(vector<int> a, int b) {
    vector<int> c;
    int t = 0; //进位
    for (int i = 0; i < a.size() || t; i++) {
        if (i < a.size()) t += a[i] * b;
        c.push_back(t % 10); //将当前位数字存入结果数组中
        t /= 10; //更新进位状态
    }
    return c;
}

除法

我们采用逐位除法的方法进行高精度除法。将每一位的商都算出来,并且考虑到余数的情况。

以下是C++代码示例:

vector<int> div(vector<int> a, int b, int& r) {
    vector<int> c;
    r = 0; //余数
    for (int i = a.size() - 1; i >= 0; i--) {
        r = r * 10 + a[i];
        c.push_back(r / b); //将当前位商存入结果数组中
        r %= b; //更新余数状态
    }
    reverse(c.begin(), c.end()); //翻转数组
    while (c.size() > 1 && c.back() == 0) c.pop_back(); //删除前导零
    return c;
}

取余

取余运算与除法运算相似,只需要返回余数即可。

以下是C++代码示例:

int mod(vector<int> a, int b) {
    int r = 0; //余数
    for (int i = a.size() - 1; i >= 0; i--) {
        r = r * 10 + a[i];
        r %= b; //更新余数状态
    }
    return r;
}

示例

我们可以用高精度运算来计算1000的阶乘和1到1000的和。

#include <iostream>
#include <vector>
using namespace std;

vector<int> mul(vector<int> a, vector<int> b) { //高精度乘法
    vector<int> c(a.size() + b.size());
    for (int i = 0; i < a.size(); i++)
        for (int j = 0; j < b.size(); j++)
            c[i + j] += a[i] * b[j];
    for (int i = 0; i < c.size() - 1; i++) { //进位
        c[i + 1] += c[i] / 10;
        c[i] %= 10;
    }
    while (c.size() > 1 && c.back() == 0) c.pop_back(); //删除前导零
    return c;
}

vector<int> add(vector<int> a, vector<int> b) { //高精度加法
    vector<int> c;
    int t = 0; //进位
    for (int i = 0; i < a.size() || i < b.size() || t; i++) {
        if (i < a.size()) t += a[i];
        if (i < b.size()) t += b[i];
        c.push_back(t % 10);
        t /= 10;
    }
    while (c.size() > 1 && c.back() == 0) c.pop_back(); //删除前导零
    return c;
}

int main() {
    vector<int> res(1, 1); //res初始为1
    for (int i = 1; i <= 1000; i++) { //计算阶乘
        vector<int> p;
        int t = i;
        while (t) { //将i转换为数组
            p.push_back(t % 10);
            t /= 10;
        }
        if (p.empty()) p.push_back(0); //防止空数组
        res = mul(res, p);
    }
    int sum = 0;
    for (int i = 1; i <= 1000; i++) { //计算和
        vector<int> p;
        int t = i;
        while (t) { //将i转换为数组
            p.push_back(t % 10);
            t /= 10;
        }
        if (p.empty()) p.push_back(0); //防止空数组
        res = add(res, p);
    }
    reverse(res.begin(), res.end()); //翻转数组
    for (int i = 0; i < 10; i++) { //输出前10位
        cout << res[i];
    }
    cout << endl;
    return 0;
}

总结

本篇文章介绍了C/C++实现高精度运算的方法,并给出了加法、减法、乘法、除法和取余的函数实现示例。我们可以利用高精度运算计算大数的阶乘、和等复杂运算。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C/C++高精度运算(大整数运算)详细讲解 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • 深入解析C++编程中线程池的使用

    深入解析C++编程中线程池的使用 什么是线程池? 线程池是一种用来集中处理线程的机制。线程池内包含多个线程,它们可以处理分配给线程池的任务。线程池在系统启动时就被初始化,一直运行到系统关闭。 为什么需要使用线程池? 线程池的好处是可以优化系统性能,通过重复利用已存在的线程,避免了频繁创建和销毁线程的开销。并且线程池可以缓解程序因为大量线程占用系统资源,导致系…

    C 2023年5月22日
    00
  • C语言实现动态顺序表的实现代码

    让我来为大家详细讲解一下如何使用C语言实现动态顺序表的实现代码。 1. 动态顺序表的概述 动态顺序表是一种线性表,它基于数组实现。动态顺序表可以自动扩充或缩小其容量以存储数据。动态顺序表中元素的位置是按照它们在数组中的位置来确定的。它们在内存中是连续存储的,因此它们可以通过下标快速访问。 2. 动态顺序表的实现 我们使用C语言的方法来实现动态顺序表。首先,我…

    C 2023年5月23日
    00
  • 解析C++哈夫曼树编码和译码的实现

    解析C++哈夫曼树编码和译码的实现 前言 哈夫曼树是一种经典的数据结构,常用于数据压缩和编解码等场景。其中,哈夫曼树的编码和译码是哈夫曼编码最核心的两个操作。 本篇文章将详细讲解如何使用C++实现哈夫曼树的编码和译码,包括以下内容: 哈夫曼树的构建 哈夫曼编码的生成 哈夫曼编码的压缩 哈夫曼编码的解压 哈夫曼树的构建 哈夫曼树的构建需要先计算出每个字符出现的…

    C 2023年5月24日
    00
  • C 程序 使用指针交换两个数字

    很好,C 程序使用指针交换两个数字的完整使用攻略如下: 1. 准备工作 在开始编写 C 程序之前,你需要确保已经安装好了 C 语言编译器。如果还没有安装,可以先安装 GCC 编译器,具体可以参考网上相关教程进行安装。 2. 编写代码 下面是一个简单的 C 程序,用于交换两个数字: #include <stdio.h> void swap(int …

    C 2023年5月9日
    00
  • 基于Java中Math类的常用函数总结

    基于Java中Math类的常用函数总结 简介 Java的Math类为开发者提供了许多数学方法,使用这些方法能够方便地对数据进行处理和计算。本篇文章将对Java中Math类的一些常用函数进行总结和详细讲解,包括:绝对值函数、对数函数、三角函数等。 绝对值函数 绝对值函数在数学中也称为模函数,是一个常用的函数。在Java中,可以使用Math类中的abs函数来计算…

    C 2023年5月22日
    00
  • 将Emacs打造成强大的Python代码编辑工具

    当你选择使用 Emacs 作为 Python 的编辑器时,你会拥有一个非常强大的工具,Emacs 配合一些插件和定制的设置,可以满足你对 Python 编辑器的所有需求。 下面是将 Emacs 打造成强大的 Python 代码编辑工具的攻略: 安装 Python 模式 首先,你需要安装一个称为“Python 模式”的软件包。该软件包提供了一些有用的功能,如代…

    C 2023年5月23日
    00
  • Lua中的一些常用函数库实例讲解

    我来为你讲解“Lua中的一些常用函数库实例讲解”的完整攻略。 Lua中的一些常用函数库实例讲解 1. string库 string库是Lua中的一个基本库,提供了一系列的字符串操作函数。下面分别介绍几个常用的函数: 1.1 string.sub(string, i [, j]) 该函数用于返回从字符串string的第i个字符开始到第j个字符结束的子串。如果j…

    C 2023年5月22日
    00
  • js 将json字符串转换为json对象的方法解析

    下面是关于 “js 将json字符串转换为json对象的方法解析” 的完整攻略: 什么是 JSON JSON(JavaScript Object Notation)是一种轻量级数据交换格式。JSON 被设计成易于读写和解析,同时也易于生成和解析。JSON 使用 JavaScript 语法,但是 JSON 格式作为独立的数据格式存在于多种编程语言中。 JSON…

    C 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部