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

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日

相关文章

  • json中换行符的处理方法示例介绍

    对于”json中换行符的处理方法示例介绍”这个话题,下面我将进行详细讲解。 1. 问题描述 在JSON数据中,如果包含了换行符,我们在解析JSON字符串的时候很有可能会遇到一些问题。因此需要对JSON字符串中的换行符进行处理,以避免出现解析JSON时出错的情况。 2. 处理方法 2.1 用转义字符代替换行符 JSON字符串中的换行符可以用转义字符\n代替,这…

    C 2023年5月23日
    00
  • 详解基于C++实现约瑟夫环问题的三种解法

    详解基于C++实现约瑟夫环问题的三种解法 约瑟夫问题 约瑟夫问题是一个经典的问题,是一个圆圈里面有$n$个数字,从中每次删除第$m$个数字,求出每次删除的数字。简单的说,约瑟夫问题就是$n$个人围成一圈,从第一个人开始报数,报到$m$的人出圈,直到计算到最后一个人。 解法一:使用递推(模拟游戏过程) 思路:利用递归的思想模拟即可。假如最后剩下一个数据,则保留…

    C 2023年5月22日
    00
  • C程序 将一个数组的所有元素复制到另一个数组

    下面我来详细讲解如何编写一份 C 程序来将一个数组的所有元素复制到另一个数组。 问题描述 假设有两个整型数组 arr1 和 arr2,现在的任务是将 arr1 的所有元素复制到 arr2 中。 思路分析 这个问题可以通过创建一个循环来实现,遍历 arr1 的所有元素并将其逐个复制到 arr2 中。因此,我们将创建一个 for 循环,并在循环中执行一个赋值操作…

    C 2023年5月9日
    00
  • C++详解如何通过模板实现元素的反序

    当我们需要对一组数据进行反序操作时,可以通过模板来实现。下面就详细说明如何通过模板实现元素的反序操作: 1. 利用模板实现反序函数 我们可以通过模板函数将需要反序的数组作为参数传递进去,然后在函数中进行元素反转操作,最后返回反序后的数组。下面是一段通过模板实现反序函数的代码示例: template<typename T> void Reverse…

    C 2023年5月23日
    00
  • C4D怎么建模三维立体的摩天轮?

    当我们要建模三维立体的摩天轮时,通常需要经过以下步骤: 步骤一:创建摩天轮主体的外形 这个步骤可以用多边形建模实现。我们可以先创建轮廓线,然后再为其赋予一个融合体(Extrude)属性来进行外形建模。这里我们用一个圆形作为轮廓线的基础。具体步骤如下: 打开C4D,再打开新建一个工程。 将“多边形建模”界面的开关打开。(然后,将视图模式切换至左视图模式) 将圆…

    C 2023年5月22日
    00
  • C++超详细讲解引用和指针

    C++超详细讲解引用和指针 什么是指针和引用 在C++中,指针和引用是两种重要的数据类型。 指针是一个变量,存储一块内存的地址;而引用则是一种别名,可以让我们通过一个名称来访问另一个变量或对象。 指针的声明和使用 指针的声明需要指定指针所指向的类型,并使用星号(*)进行标识。例如,声明一个指向整数类型的指针如下: int* ptr; 指针的使用需要注意以下几…

    C 2023年5月22日
    00
  • C if else if ladder

    C 语言中的 if else if 梯形结构又被称作 if else if ladder,它是多个条件语句的嵌套,可以用来实现复杂的条件判断。以下是 if else if ladder 的完整使用攻略: 梯形结构语法格式 if (condition1) { statement1; } else if (condition2) { statement2; } …

    C 2023年5月9日
    00
  • C语言 strcat()函数

    当我们需要将两个字符串连接在一起时,可以使用C语言中的strcat()函数。它可以把两个字符串拼接起来,并返回结果字符串的地址。 函数原型 char *strcat(char *dest, const char *src); 该函数有两个参数: dest:需要被追加的目标字符串。 src:需要追加的源字符串。 函数返回值是一个指向目标字符串的指针。需要注意的…

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