详解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++实现一个简单的学生成绩管理系统。 系统需求 学生成绩管理系统需要实现的功能如下: 增加学生信息,包含学号、姓名及出生年月日 增加学生课程成绩信息,包含课程编号、课程名称及成绩 修改学生信息及学生课程…

    C 2023年5月23日
    00
  • C++全面精通类与对象

    C++全面精通类与对象攻略 什么是类和对象 在C++中,类(class)是一种自定义数据类型,可以用来描述具有相同属性和方法的一组对象。而对象(object)则是类的一个具体实例。 类是一个抽象的概念,它定义了数据类型的属性和方法,包括数据成员和成员函数,但并不占用内存空间。而对象则是类的一个具体实体,它占用实际的内存空间,可以使用类提供的属性和方法进行操作…

    C 2023年5月22日
    00
  • C语言动态内存管理malloc柔性数组示例详解

    C语言动态内存管理malloc柔性数组示例详解 什么是动态内存管理 动态内存管理是避免预定义变量长度无法适应实际大小的常见方法。在C语言中,动态内存分配和回收函数是malloc()和free()。 malloc的基本语法和用法 malloc()的原型如下: void *malloc(size_t size); 其中,参数size是所需内存块的字节数。该函数返…

    C 2023年5月23日
    00
  • 荣耀畅玩8C手机怎么样?荣耀畅玩8C全面评测

    荣耀畅玩8C手机怎么样?荣耀畅玩8C全面评测 前言 荣耀畅玩8C是一款2018年10月上市的入门级智能手机。作为荣耀畅玩系列产品的一员,荣耀畅玩8C主打高性价比,具有充足的配置和不错的性能表现。在这篇文章中,我们将对荣耀畅玩8C进行全面评测,从外观、配置、性能以及其他方面对其进行详细剖析。 外观设计 荣耀畅玩8C采用了6.26英寸的水滴屏,分辨率为1520x…

    C 2023年5月22日
    00
  • qq2440启动linux后插入u盘出现usb 1-1: device descriptor read/64, error -110,usb 1

    针对“qq2440启动linux后插入u盘出现usb 1-1: device descriptor read/64, error -110,usb 1”的问题,我们可以尝试以下几个步骤进行排查和解决: 1. 检查硬件连接 首先,我们需要确定u盘插入是否有松动或接触不良等硬件问题。可以将u盘重新插拔几次并检查连接是否紧密。如果问题仍然存在,可以考虑更换其他的u…

    C 2023年5月24日
    00
  • 关于C++友元类的实现讲解

    关于C++友元类的实现讲解 什么是友元类 在C++中,我们可以通过友元类实现类与类之间的访问权限互相扩展,允许一个类的非成员函数或其他类的成员函数访问它的私有成员。 友元类是指在一个类中访问另一个类的私有或受保护成员,需要在另一个类的定义中将该类声明为友元类。 实现步骤 1.在目标类中声明友元类 在目标类中声明友元类的方式如下: friend class C…

    C 2023年5月23日
    00
  • C#实现集合转换成json格式数据的方法

    下面是一份详细的攻略,旨在讲解如何使用C#实现将集合转换为JSON格式数据的方法。 1. 什么是JSON JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人们阅读和编写,也易于机器解析和生成,是现代应用程序中常用的数据交换格式之一。 2. C#的JSON解析库 在C#中,我们可以使用JSON解析库来将对象转换为…

    C 2023年5月23日
    00
  • C语言用指针支持树

    关于“C语言用指针支持树”的完整使用攻略,我准备分为以下几个部分进行讲解: 树的定义与基本操作 使用指针实现树节点 树的遍历算法 示例程序 树的定义与基本操作 树是一种非常常见的数据结构,其结构非常清晰,由若干个节点组成,每个节点之间有唯一的父子关系。 一些常见的树操作包括: 插入节点:在树中插入一个新节点,将其作为指定节点的子节点。 删除节点:从树中删除给…

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