大数的运算
Posted programchen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了大数的运算相关的知识,希望对你有一定的参考价值。
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 }
以上是关于大数的运算的主要内容,如果未能解决你的问题,请参考以下文章