详解C/C++高精度(加减乘除)算法中的压位优化

详解C/C++高精度(加减乘除)算法中的压位优化

什么是高精度算法?

高精度算法(又叫大数算法)是指可以处理比计算机支持的最大数值范围更大的数值计算方法。在C/C++中,int类型变量的最大范围一般为2^31-1即2147483647,而long long型变量的最大范围一般为2^63-1即9223372036854775807。如果需要处理比这更大的数字,则无法使用普通的数据类型进行计算,需要使用高精度算法来处理。

为什么需要压位优化?

高精度算法是通过将大数拆分成若干个小数的方式来进行计算的。例如,“12345678901234567890”可以拆分成“1234567890”和“1234567890”,然后进行逐位相加或相乘,得出最终答案。这种拆分操作会产生很多的进位(或借位)操作,导致算法效率不高。而压位优化则可以有效降低进位(或借位)的次数,提高算法效率。

压位优化的具体实现方法

压位优化的实现方法比较简单,只需要将高精度算法中的拆分操作重新定义,使得可以同时处理更多位数的数字。具体来说,可以先将高精度数值按照32位(或64位)一组进行划分,再进行计算。

具体实现方法可以参考以下代码:

#include <bits/stdc++.h>
using namespace std;

const int BASE = 1000000000;
const int WIDTH = 9;

typedef long long ll;

struct BigInt {
    vector<int> s;

    BigInt& clean() {while(!s.back() && s.size() > 1) s.pop_back(); return *this;}

    BigInt(ll num = 0) {*this = num;}
    BigInt(string s) {*this = s;}

    BigInt& operator = (long long num) {
        s.clear();
        do {
            s.push_back(num % BASE);
            num /= BASE;
        } while (num > 0);
        return *this;
    }

    BigInt& operator = (const string& str) {
        s.clear();
        int x, len = (str.length() - 1) / WIDTH + 1;
        for (int i = 0; i < len; i++) {
            int end = str.length() - i*WIDTH;
            int start = max(0, end - WIDTH);
            sscanf(str.substr(start,end-start).c_str(), "%d", &x);
            s.push_back(x);
        }
        return (*this).clean();
    }

    BigInt operator + (const BigInt& b) const {
        BigInt c;
        c.s.clear();
        for (int i = 0, g = 0; ; i++) {
            if (g == 0 && i >= s.size() && i >= b.s.size()) break;
            int x = g;
            if (i < s.size()) x += s[i];
            if (i < b.s.size()) x += b.s[i];
            c.s.push_back(x % BASE);
            g = x / BASE;
        }
        return c;
    }

    BigInt operator * (const BigInt& b) const {
        vector<ll> num(s.size()+b.s.size(), 0);
        for (int i = 0; i < s.size(); i++)
            for (int j = 0; j < b.s.size(); j++)
                num[i+j] += (ll)s[i] * b.s[j];

        BigInt c;
        c.s.clear();
        for (int i = 0, g = 0; ; i++) {
            if (g ==0 && i >= num.size()) break;
            ll x = num[i] + g;
            c.s.push_back(x % BASE);
            g = x / BASE;
        }
        return c.clean();
    }

    // ...

};

int main() {
    BigInt a, b, c;
    a = "1234567890123456789012345678901234567890";
    b = "1098765432109876543210987654321098765432109876543210";
    c = a + b;
    cout << c << endl;
    return 0;
}

在以上代码中,对高精度数字的拆分操作被重新定义为32位的数字组,在进行加法和乘法操作时,可以同时处理更多的位数,降低进位和借位的次数,提高算法效率。

示例说明

以下是使用以上代码进行加法运算的示例:

BigInt a, b, c;
a = "1234567890123456789012345678901234567890";
b = "1098765432109876543210987654321098765432109876543210";
c = a + b;
cout << c << endl;

以上代码中,首先声明了三个BigInt类型的变量a、b、c,并通过字符串的方式将大数赋值给a和b。然后通过c = a + b的方式进行加法操作,最终输出结果。由于使用了压位优化,计算速度比普通的高精度算法要快很多。

另外一个使用压位优化进行高精度乘法的示例代码如下:

BigInt a, b, c;
a = "1234567890123456789012345678901234567890";
b = "1098765432109876543210987654321098765432109876543210";
c = a * b;
cout << c << endl;

以上代码中,同样使用了压位优化的乘法函数,可以同时处理更多的位数,提高计算效率。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解C/C++高精度(加减乘除)算法中的压位优化 - Python技术站

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

相关文章

  • C语言文件操作实现数据持久化(帮你快速了解文件操作函数)

    C语言文件操作实现数据持久化(帮你快速了解文件操作函数) 数据持久化是指将程序中的数据保存到外部文件中,以便下次程序启动时可以读取保存的数据,从而达到数据持久化的目的。C语言提供了一系列文件操作函数,可以方便地实现数据持久化功能。 文件的打开与关闭 在对文件进行操作之前,需要先打开文件。可以使用fopen函数打开文件,语法如下: FILE *fopen(co…

    C 2023年5月22日
    00
  • angular指令笔记ng-options的使用方法

    下面我将详细讲解“angular指令笔记ng-options的使用方法”的完整攻略。首先,让我们来看一下ng-options的作用是什么。 什么是ng-options ng-options是AngularJS中的一条指令,它用于创建选项列表。在使用这个指令时,我们可以简单地通过设置相关的属性来定义可选项。ng-options指令通常与ng-model指令一起…

    C 2023年5月22日
    00
  • C++AVL树4种旋转详讲(左单旋、右单旋、左右双旋、右左双旋)

    C++AVL树4种旋转详讲 什么是AVL树? AVL树是一种自平衡二叉搜索树,它在插入或删除一个节点时,会通过旋转操作进行自平衡。AVL树的特点是保证树的高度始终保持在O(logN)的水平,从而保证了树的查询、插入、删除等操作时间复杂度保持在O(logN)的水平。因此在大规模数据的场景下,使用AVL树能够取得很好的性能表现。 AVL树的基本操作 AVL树的基…

    C 2023年5月22日
    00
  • 深入理解Commonjs规范及Node模块实现

    深入理解 CommonJS 规范及 Node 模块实现 什么是 CommonJS 规范? CommonJS 是 JavaScript 社区为了解决缺少适用于服务器端的 Module 标准而提出的一种模块化规范。其最初的定位是为了规范模块文件、模块导入、模块导出等相关概念。CommonJS 规范将所有的代码都认为是一个模块,每个模块有自己的作用域,可以定义变量…

    C 2023年5月23日
    00
  • C++实现简单班级成绩管理系统

    C++实现简单班级成绩管理系统攻略 1. 需求分析 在实现班级成绩管理系统前,首先需要明确实现系统的主要功能,如本系统需要实现的功能有:- 添加学生的基本信息,包括学生姓名和学号;- 添加学生成绩信息,包括数学、语文、英语等科目的成绩;- 对学生成绩进行管理,包括查看某个学生的成绩、某个科目的平均成绩、班级总体平均成绩等。 2. 设计思路 本系统的设计思路为…

    C 2023年5月30日
    00
  • C语言中字符串和数字的相互转换实现代码

    C语言中字符串和数字的相互转换是常见的编程操作。下面是一些实现代码,以便帮助你进行相应的转换。 将字符串转换为数字 C语言中,字符串可以使用标准库函数 atoi() 转换为整数。由于 atoi() 是标准库函数,因此需要包含头文件 <stdlib.h>。 #include <stdio.h> #include <stdlib.h…

    C 2023年5月24日
    00
  • Android中gson、jsonobject解析JSON的方法详解

    Android中gson、jsonobject解析JSON的方法详解 什么是JSON JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它基于JSON的数据格式来描述数据对象。JSON是一种数据存储格式,它和XML的作用类似,但JSON是一种轻量级的、更易于读写的数据格式。JSON中的数据可以是数组或对象,通过层级的…

    C 2023年5月23日
    00
  • IOS-MVC层读取服务器接口JSON数据

    首先,在IOS中采用MVC设计模式可以有效地解耦、优化代码结构以及方便代码管理。在读取服务器接口JSON数据时,我们可以采用以下步骤: 创建一个Model类:定义与服务器端数据对应的模型,一般以属性的形式表示。 @interface User : NSObject @property (nonatomic, strong) NSString *name; @…

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