大数的运算

C++中,int占用4字节,32比特,数据范围为-2147483648~2147483647[-2^31~2^31-1]。

uint型为无符号32位整数,占4个字节,取值范围在0~4,294,967,295之间。

但是如果需要计算的数据比这个范围更大呢?使用long ,long long ?但是如果数据更大呢?如何进行大数的计算。

通常这个情况下我们会使用string来对数据进行运算。从而达到对这个庞大的数字进行操作。

//模拟加法的运算
string add(string num1, string num2)
{
    //位数补齐
    int len1 = num1.size();
    int len2 = num2.size();
    int diffNum = abs(len1 - len2);
    int longSize = len1 > len2 ? len1 : len2;
    if (len1 < len2)
    {
        num1.insert(0, diffNum, ‘0‘);
    }
    else if (len2 < len1)
    {
        num1.insert(0, diffNum, ‘0‘);
    }
    string ret;
    ret.resize(longSize);
    //逐位相加
    int step = 0;
    for (int i = longSize - 1; i >= 0; i--)
    {
        ret[i] = (num1[i] - ‘0‘) + (num2[i] - ‘0‘) + step;
        ret[i] += ‘0‘;
        //更新
        if (ret[i] > ‘9‘)
        {
            ret[i] -= 10;
            step = 1;
        }
        else step = 0;
    }
    if (step == 1)
    {
        ret.insert(0, 1, ‘1‘);
    }
    return ret;
}
 1 //模拟减法操作
 2 string sub(string num1, string num2)
 3 {
 4     //位数补齐
 5     int len1 = num1.size();
 6     int len2 = num2.size();
 7     int diffNum = abs(len1 - len2);
 8     int longSize = len1 > len2 ? len1 : len2;
 9     if (len1 < len2)
10     {
11         num1.insert(0, diffNum, ‘0‘);
12     }
13     else if (len2 < len1)
14     {
15         num1.insert(0, diffNum, ‘0‘);
16     }
17     string ret;
18     ret.resize(longSize);
19     //逐位相减
20     for (int i = longSize - 1; i >= 0; i--)
21     {
22         //判断是否需要借位
23         if (num1[i] < num2[i])
24         {
25             num1[i] += 10;
26             //更新高位
27             num1[i - 1]--;
28         }
29         ret[i] = (num1[i] - ‘0‘) - (num2[i] - ‘0‘);//相减完后变回字符
30
31     }
32     //删除前置0
33     while (ret.size() > 1 && ret[0] == ‘0‘)
34     {
35         ret.erase(0, 1);
36     }
37     return ret;
38 }
 1 pair<string, string> dev(string num1, string num2)
 2 {
 3     string ret; //商
 4     string rem = num1; //余数
 5     int diffNum = num1.size() - num2.size();//给除数放大
 6     num2.append(diffNum, ‘0‘);
 7     for (int i = 0; i <= diffNum; i++)
 8     {
 9         //记录减法执行的次数
10         char count = ‘0‘;
11         while (1)
12         {
13             if (less(rem, num2))
14             {
15                 break;
16             }
17             rem = sub(rem, num2);
18             count++;
19         }
20         ret += count;
21         num2.pop_back();//除数减小10倍
22     }
23     //去零
24     while (ret.size() > 1 && ret[0] == ‘0‘)
25     {
26         ret.erase(0, 1);
27     }
28     return make_pair(ret, rem); //返回<商,余数>
29
30 }
 1 string mul(string num1, string num2)
 2 {
 3     //简化乘法的过程
 4     if (num2.size() > num1.size())
 5     {
 6         swap(num2, num1);
 7     }
 8     string ret = "0";
 9     for (int i = num2.size() - 1; i >= 0; i++)
10     {
11         //获取当前位乘数的值
12         int curDigit = num2[i] - ‘0‘;
13         int step = 0;
14         //当前位乘积的结果
15         string tmp = num1;
16         for (int j = tmp.size(); j >= 0; j--)
17         {
18             //逐位相乘
19             tmp[j] = (tmp[j] - ‘0‘) * curDigit + step;
20             //更新进位
21             if (tmp[j] > 9)
22             {
23                 step = tmp[j] / 10;
24                 tmp = tmp[j] % 10;
25             }
26             else step = 0;
27             tmp[j] += ‘0‘;//还原成字符
28         }
29         //最后判断是否需要进位
30         if (step > 0)
31         {
32             tmp.insert(0, 1, step + ‘0‘);
33         }
34         //补零
35         tmp.append(num2.size() - 1 - i, ‘0‘);
36         //累加一次乘法的结果
37         ret = add(ret, tmp);
38     }
39     return ret;
40 }

原文地址:https://www.cnblogs.com/programchen/p/12353371.html

时间: 2024-10-17 08:23:57

大数的运算的相关文章

hdu4927 Series 1(组合+公式 Java大数高精度运算)

题目链接: Series 1 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 423    Accepted Submission(s): 146 Problem Description Let A be an integral series {A1, A2, . . . , An}. The zero-order series o

Acdream 1210 Chinese Girls&#39; Amusement(大数模板运算 + 找规律)

传送门 Chinese Girls' Amusement Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) Submit Statistic Next Problem Problem Description You must have heard that the Chinese culture is quite different from that of Europe or Rus

大数高精度运算(模板)

前言:高精度运算.是指參与运算的数(加数.减数,因子--)范围大大超出了标准数据类型(整型,实型)能表示的范围的运算. 模板:包含大数加减乘除.大数与int数的乘法,模板能够不断扩充. 代码: /* 所有亲測可用,可是不能用于负数的运算,仅仅能对正数进行大数运算 */ const int ten[4]= {1,10,100,1000}; const int maxl = 300; struct BigNumber { int d[maxl]; char s[maxl]; BigNumber(co

大数各种运算

大数模板l #include<iostream> #include<cstring> #include<iomanip> #include<algorithm> #include<cstdio> using namespace std; #define MAXN 9999 #define MAXSIZE 10 #define DLEN 4 struct BigNum { int a[500]; //可以控制大数的位数 int len; //大数长

js如何实现大数的运算?

对于非常大或非常小的数,可以用科学记数法表示浮点值.采用科学记数法,可以把一个数表示为数字加e/E,后面加乘以10的倍数,如: var num1 = 3.125e7; // 31250000 var num2 = 3e-17; // 0.00000000000000003 进行特别大的数的加减运算,可以使用字符串+科学记数法的方法来进行,如: // 这里只考虑大整数的情况,不考虑小数 function strAdd(sNum1, sNum2){ /*增加一位数位以记录最高位进一的情况*/ var

Java实现大数加法运算的几种方法

大数加法 思路一:定义String变量str1和str2分别存储输入的两个大数,定义num1[]和num2[]两个int型数组,将两个字符串分别逐个字符逆序存入数组,定义sum[]数组存放求和结果,使用循环两个数组中的元素逐位相加,并判断是否进位,最后逆序输出数组sum[]中的每个元素. 1 import java.util.Scanner; 2 3 public class largenumberOperationAdd { 4 public static void main(String[]

大数的运算--阶乘

今天复习了一下求阶乘 题目:编写一个程序,可以输出10000内的阶乘 #include <cstdio> #include <cstdlib> #include <cstring> #define max_w 8002 #define base 100000 int ans[10002][max_w]; int wei[10002]; int calMulti(int n) { int ci = 0; for(int i = 0; i < wei[n-1]; i+

[编程题]大数的运算

题目:输入某个数,计算它乘以2的结果 #include <iostream> #include <string> #pragma warning(disable : 4996) using namespace std; string multiply2(string &str) { int len = str.size(); if (len == 0) return "0"; string result = str; int location = len

HDOJ-1041 Computer Transformation(找规律+大数运算)

http://acm.hdu.edu.cn/showproblem.php?pid=1041 有一个初始只有一个1的串 每次都按①0 -> 10;②1 -> 01;这两条规则进行替换 形如:n = 1  1 n = 2  01 n = 3  1001 ... 求经过n步替换之后 串中只含复数个0的连续子串(不难发现,这种子串只能是‘00’)的出现次数 因为0<n<=1000的限制 在最坏情况下(n==1000)串的长度将达到2^1000位 排除了直接模拟上述替换过程的可能 列出前几