大整数的存储与加减乘除四则运算

当需要计算的整数或计算结果可能会超出long long 所能表示的范围时,应该用大整数来存储和计算(Java里面有BigInteger来存储大整数,这里讨论的是C++语言)。

大整数的存储形式是下面这个结构体(包含了构造函数):

// 大整数结构体
struct bign{
    int d[1000];
    int len;

    bign(){
        memset(d, 0, sizeof(d));
        len = 0;
    }
};

首先以字符串的形式读去数据,然后将字符串逐个逆序字符存入d[]数组(可以采用用reverse函数将字符串进行反转,然后正序逐个赋值),len记录整数的长度。

change()转换函数(完成字符串到bign结构体的转换)

// 将整数的字符串形式转换成bign结构体形式
bign change(char str[]){    // 将整数转换为bign
    bign a;
    a.len = strlen(str);        // bign的长度就是字符串的长度
    for (int i = 0; i < a.len; i++){
        a.d[i] = str[a.len - i - 1] - ‘0‘;        // 逆着赋值
    }
    return a;
}

在对两个大整数进行减法时要先比较减数和被减数的大小,如果减数大于被减数,则两个整数交换位置,所以还需要一个比较函数

compare()比较函数(比较两个数的大小 如果a > b,那么返回1, 如果 a < b, 返回-1,否则返回0)

// 比较两个数的大小 如果a > b,那么返回1, 如果 a < b, 返回-1,否则返回0
int compare(bign a, bign b){
    if (a.len > b.len)
        return 1;            // a更大
    else if (a.len < b.len)
        return -1;
    else{
        for (int i = a.len - 1; i >= 0; i--){
            if (a.d[i] > b.d[i])                // 只要有一位a大,则a更大
                return 1;
            else if (a.d[i] < b.d[i])
                return -1;
        }
        return 0;            // 两数相等
    }
}

1. 大整数的加法:

将该位上的两个数字以及来自低位的进位相加,得到的结果的个位表示该位结果,十位数作为新的进位

bign add(bign a, bign b){            // 高精度 a + b
    bign c;
    int carry = 0;            // carry是进位
    for (int i = 0; i < a.len || i < b.len; i++){    // 以较长的为界限
        int temp = a.d[i] + b.d[i] + carry;            // 两个对应位与进位相加
        c.d[c.len++] = temp % 10;            // 个位数为该位结果
        carry = temp / 10;                    // 十位数为新的进位
    }
    if (carry != 0){
        c.d[c.len++] = carry;            // 如果最后进位不为0,则直接赋给结果的最高位
    }
    return c;
}

2. 大整数之间的减法

使用下面这个函数前要先比较两数绝对值大小,如果被减数小于减数,需要交换两个变量,然后输出符号,再使用sub函数

 1 bign sub(bign a, bign b){
 2     bign c;
 3     for (int i = 0; i < a.len || i < b.len; i++){
 4         if (a.d[i] < b.d[i]){        // 如果不够减
 5             a.d[i + 1]--;            // 向高位借位
 6             a.d[i] += 10;            // 当前位加10
 7         }
 8         c.d[c.len++] = a.d[i] - b.d[i];        // 减法结果作为当前结果
 9     }
10     while (c.len - 1 >= 1 && c.d[c.len - 1] == 0){
11         c.len--;            // 去除高位的0,同时至少保留一位最低位
12     }
13     return c;
14 }

3. 大整数和整数的乘法(一个大整数乘以一个整数):

  用从大整数a 的低位开始,用大整数的每一位乘以给定的整数,然后加上进位,每一次的结果对10取余就是结果变量c在当前索引的数值,每一次的结果除以10作为新的进位,遍历完 a 的所有数位后,如果表示进位的变量不为零,则应该将这个变量逐位的加到 c 的最高位,直到这个进位变量为0

 1 bign multi(bign a, int b){
 2     bign c;
 3     int carry = 0;
 4     for (int i = 0; i < a.len; i++){
 5         int temp = a.d[i] * b + carry;
 6         c.d[c.len++] = temp % 10;
 7         carry = temp / 10;                // 高位部分作为新的进位
 8     }
 9     while (carry != 0){
10         c.d[c.len++] = carry % 10;
11         carry /= 10;
12     }
13     return c;
14 }

  如果两个整数刚好一正一负,那么先输出符号,然后将绝对值带入函数计算。

4. 大整数和整数的除法(一个大整数除以一个整数):

 1 bign divide(bign a, int b, int &r){            // r为余数
 2     bign c;
 3     c.len = a.len;
 4     for (int i = a.len - 1; i >= 0; i--){    // 从高位开始
 5         r = r * 10 + a.d[i];        // 和上一位遗留的余数组合
 6         if (r < b)
 7             c.d[i] = 0;        // 不够除,该位为0
 8         else{
 9             c.d[i] = r / b;    // 商
10             r  = r % b;        // 获得新的余数
11         }
12     }
13     while (c.len - 1 >= 1 && c.d[c.len - 1] == 0){
14         c.len--;            // 去除高位的0,同时至少保留一位最低位
15     }
16     return c;
17 }

练习题:PAT B1017   PAT A1023

本博客大部分取自胡凡的《算法笔记》和《算法笔记上机训练》

原文地址:https://www.cnblogs.com/hi3254014978/p/12233200.html

时间: 2024-10-08 22:32:28

大整数的存储与加减乘除四则运算的相关文章

大整数运算

对于A,B的范围在int范围内,求解A与B的加减乘除运算我相信大家很快就可以写出程序来,但是如果A,B是有着1000个数位的整数呢?恐怕就没有已有的数据类型来表示了,这时候只能老实的模拟加减乘除运算的过程.模拟加减乘除的运算的过程,原理就是小学的. 大整数又称为高精度整数,其含义就是用基本的数据类型无法存储其精度的整数.大整数运算即高精度运算. 首先,介绍大整数的存储. 很简单,用数组即可.例如,int型数组d[1000]:如将123456存储到数组中,则有d[0]=6,d[1]=5......

大整数四则运算

============ 日后再写!先将设计思想留下 ============= 定义并实现超长整数类double long,要求如下: 64位数据长度,有符号 支持+.-.*./运算 支持+=.-=./=运算 支持cin>>和cout<<操作 首先,我们的运算对象是大整数并且要支持cout<<和cin>>操作,数组和链表是可选择项.在这里我们用数组.数组有int型和char型,选哪个好呢?只能选char型,因为我们的大整数是有符号位的,必须用一个char字

大整数的加减乘除

多项式的加减乘除能够利用多项式的加减乘除进行运算,所以下面程序採用了多项式的加减乘除.多项式运算已经在<算法导论>第30章有简要的介绍,详细的请參考数学书. 大整数加法:(利用书上公式轻松得出) //多项式加法-大数加法 #include <iostream> #include <time.h> using namespace std; #define m1 4 #define m2 5 //a[0]=x^0 a[1]=x^1....a[n]=x^n的关于x的多项式系数

大整数四则运算(vector)

目录 基础 1. 高精度加法 2. 高精度减法 3. 高精度乘低精度 4. 高精度除以低精度 5. 高精度乘高精度 6. 高精度除以高精度 综合 总结 每逢大整数四则运算,都会怯懦,虽是算法竞赛必会的东西,也零散的学过,简单的总结过,但不成体系的东西心里一直没底. 所以今天消耗了大量的卡路里,啃了几套模板之后终于总结成了一套自己的模板 再也不用担心大整数啦 基础 1. 高精度加法 高精度加法等同于算术加法,做单个的加法运算之后存下进位 A和B都为正整数 vector中下标为0存的是低位(以下都是

Java 实现大整数加减乘除

自己用Java实现的大整数加减乘除运算.还有可以改进的地方,有兴趣的童鞋可以加以改进.仅供参考,请勿转载! package barrytest; import java.util.ArrayList;import java.util.List;import java.util.regex.Matcher;import java.util.regex.Pattern; //@author Barry Wang// all the four method have not considered th

关于大整数的加减乘除求余运算 java

自己用java 实现了大字符串整数的加减乘除和求余运算, 加减法的算法是模拟手工笔算的计算过程, 除法就是从最高位不停的减操作, 乘法的算法 :遍历一个数的各个位数以及他所在位置,另一个数根据这个数的位置末位添n个0,然后累加次数为这个位置数的数值 原创代码如下: public class Demo6 { public static void main(String[]args){ System.out.println(add("-989","989")); Sys

7.2 大整数四则运算

7-2 BigInt1.c 1 #include <stdio.h> 2 #include <string.h> 3 typedef struct bigint 4 { 5 char *num; //指向长整数数组(序号0中保存着最低位) 6 char minus; //符号(1表示正数,-1表示负数) 7 int digit; //保存该数的位数(实际位数) 8 }BIGINT, *pBIGINT; 9 void BigIntTrans(pBIGINT num); //字符串转数

大整数的加减乘除C++实现

大整数的乘法由于用分治法理解起来有点困难,就采用人的计算方法实现,大整数为string 类型,结果也为string类型. 大整数的除法采用先乘后减的方法,例如: 665/20 首先20*10=200:然后665去减200,通过循环计入减了3次,则结果记入3*10=30:然后20*1=20,上次减了之后还剩65,65-20,又减了3次,所以结果记入30+3*1=33:最后还剩5,比20小,则余数为5. 大整数的加法减法和人工打草稿过程类似,不做详细分析.实现代码仅供参考: 1 #include<i

大整数运算C++1

//下面的代码勉强算是bignum_beta1版本! //实现了大整数的加减乘除四则运算,以及求两个整数的最大公约数,以及求乘法逆,miller_rabin素性检验,平方_乘法算法 //不足之处,位数还很难扩展至几千位,以及运算速度有一点慢,既然是beta1,说明bug还是挺多的 //程序缺少测试数据来测试,所以有的结果不敢保证其正确性 //由于使用c++复写了很多运算符,加入这个文件之后,大数bignum可以看做是一个如同如同int一样的基本类型 //可以像int一样加减乘除和输入输出 #in