高精度运算(C++)
高精度算法

高精度算法问题的引入由于计算机运算是有模运算,数据范围的表示有一定限制,如整型int(C++中int 与long相同)表达范围是(-2^31~2^31-1),unsigned long(无符号整数)是(0~2^32-1),都约为几十亿.如果采用实数型,则能保存最大的double只能提供15~16位的有效数字,即只能精确表达数百万亿的数。
因此,在计算位数超过十几位的数时,不能采用现有类型,只能自己编程计算。
目前在青少年信息学奥林匹克竞赛中所涉及到的高精度计算包括加(addition)、减(subtract)、乘(multiply)、除(divide)四种基本运算。
此外,在C++语言中,int类型(4个字节/32位计算机)元素存储十进制的一位数字非常浪费空间,并且运算量也非常大,因此常将程序代码优化为万进制,即数组的每个元素存储高精数字的四位。
(为什么选择万进制,而不选择更大的进制呢?十万进制中的最大值99999相乘时得到的值是9999800001超过4个字节的存储范围而溢出,从而导致程序计算错误。
)本文以暂时以10进制为例讲述高精度算法一、高精度数字的存储高精度计算通用方法:高精度计算时一般用一个数组来存储一个数,数组的一个元素对应于数的一位(当然,在以后的学习中为了加快计算速度,也可用数组的一个元素表示数的多位数字,暂时不讲),表示时,由于数计算时可能要进位,因此为了方便,将数由低位到高位依次存在数组下标对应由低到高位置上,另外,我们申请数组大小时,一般考虑了最大的情况,在很多情况下,表示有富余,即高位有很多0,可能造成无效的运算和判断,因此,我们一般将数组的第0个下标对应位置来存储该数的位数.如数:3485(三千四百八十五),表达在数组a[10]上情况是:下标0 1 2 3 4 5 6 7 8 9内容 4 5 8 4 3 0 0 0 0 0说明:位数个位十位百位千位例:一个不超过200位的非负整数,可能有多余的前导0。
高精度乘单精度乘法c++语言

高精度乘单精度乘法c++语言在C++语言中,高精度乘单精度乘法是一种精确计算方法,可以用于处理大整数和单精度浮点数的乘法运算。
在实际编程中,我们可能会遇到需要计算两个大整数或一个大整数和一个单精度浮点数的乘法运算的情况。
这时候就需要用到高精度乘单精度乘法来保证计算的准确性。
下面我们来具体讲解一下在C++语言中如何实现高精度乘单精度乘法。
首先,我们需要明确一下高精度乘单精度乘法的思路。
高精度乘法指的是对两个大整数进行乘法计算,结果可能会非常大,需要用数组或字符串来表示。
而单精度乘法指的是对两个单精度浮点数进行乘法计算,结果会是一个单精度浮点数。
在实际编程中,我们可以先将两个大整数或一个大整数和一个单精度浮点数转换为字符串或数组,然后进行逐位乘法计算,最后将结果进行合并得到最终的结果。
下面我们以一个例子来说明高精度乘单精度乘法的具体实现,在这个例子中,我们用数组来表示大整数,用double类型来表示单精度浮点数。
假设我们要计算两个大整数的乘积以及一个大整数和一个单精度浮点数的乘积,具体的代码如下:```cpp#include <iostream>#include <vector>#include <string>using namespace std;//高精度乘法string multiply(string num1, string num2) {int m = num1.size(), n = num2.size();vector<int> res(m + n, 0);for (int i = m - 1; i >= 0; i--) {for (int j = n - 1; j >= 0; j--) {int mul = (num1[i] - '0') * (num2[j] - '0');int p1 = i + j, p2 = i + j + 1;int sum = mul + res[p2];res[p1] += sum / 10;res[p2] = sum % 10;}}int i = 0;while (i < m + n && res[i] == 0) i++;if (i == m + n) return "0";string s = "";while (i < m + n) s.push_back(res[i++] + '0'); return s;}//高精度乘单精度浮点数double multiply(string num1, double num2) {string str_num2 = to_string(num2);string res_str = multiply(num1, str_num2);double res = stod(res_str);return res;}int main() {string num1 = "123456789";string num2 = "987654321";double num3 = 3.1415926;string product1 = multiply(num1, num2);double product2 = multiply(num1, num3);cout << "The product of " << num1 << " and " << num2 << " is: " << product1 << endl;cout << "The product of " << num1 << " and " << num3 << " is: " << product2 << endl;return 0;}```在这段代码中,我们首先定义了一个高精度乘法函数multiply,可以处理两个大整数的乘法。
高精度算法c++语言

高精度算法c++语言高精度算法是指在计算机科学中,用于处理大数字的算法。
这些算法通常用于数学计算、密码学、计算机图形学等领域,需要处理的数字位数可能达到数百甚至数千位。
在 C++ 中,你可以使用`<iostream>`、`<cmath>`和`<string>`头文件来实现高精度算法。
下面是一个简单的示例,演示如何使用 C++ 实现高精度整数加法:```cpp#include <iostream>#include <cmath>#include <string>using namespace std;// 高精度整数类class High Precision {private:string num; // 存储数字的字符串public:High Precision() : num("") {}High Precision(string n) : num(n) {}High Precision operator+(const High Precision& other) {High Precision result;int carry = 0;for (int i = num.size() - 1; i >= 0; i--) {int digit1 = num[i] - '0';int digit2 = other.num[i] - '0';int temp = digit1 + digit2 + carry;carry = temp / 10;temp %= 10;result.num += to_string(temp);}if (carry > 0) {result.num = to_string(carry) + result.num;}return result;}friend ostream& operator<<(ostream& os, const High Precision& num) { os << num.num;return os;}};int main() {High Precision num1("12345");High Precision num2("67890");High Precision sum = num1 + num2;cout << "Sum: " << sum << endl;return 0;}```在上述示例中,我们定义了一个名为`High Precision`的类,用于表示高精度整数。
高精度减法c++代码

以下是一个高精度减法的 C++ 代码示例,用于进行两个大整数的减法运算。
这个代码示例使用字符串来表示大整数,通过逐位计算来实现高精度减法。
```cpp#include <iostream>#include <string>#include <vector>#include <algorithm>using namespace std;// 高精度减法函数string high_precision_subtraction(string num1, string num2) {// 确保 num1 大于 num2if (num1 < num2) {swap(num1, num2);}// 创建结果字符串,初始化为 num1string result = num1;int n = num1.size();// 从最后一位开始逐位相减for (int i = n - 1; i >= 0; i--) {// 如果 num2 的第 i 位大于 num1 的第 i 位,则需要向高位借位if (num2[n - 1 - i] - '0' > num1[n - 1 - i] - '0') {result[n - 1 - i] = (num1[n - 1 - i] - '0') + 10 - (num2[n - 1 - i] - '0');for (int j = i - 1; j >= 0; j--) {if (result[j] == '0') {result[j] = '9';} else {result[j] -= 1;break;}}} else {result[n - 1 - i] = (num1[n - 1 - i] - '0') - (num2[n - 1 - i] - '0');}}// 删除结果字符串中的前导零while (result[0] == '0') {result.erase(0, 1);}return result;}int main() {string num1 = "12345";string num2 = "54321";string result = high_precision_subtraction(num1, num2);cout << num1 << " 减 " << num2 << " 的结果是:" << result << endl;return 0;}```在上述代码中,`high_precision_subtraction`函数接受两个字符串作为参数,表示要进行减法运算的两个大整数。
高精度计算--超大数运算

⾼精度计算--超⼤数运算⾼精度运算的计算思⾼精度运算计算中需要处理好以下⼏个问题: 1)数据的接收⽅法和存储⽅法 数据的接收和存储:当输⼊的数很长时,可采⽤字符串⽅式输⼊,这样可输⼊数字很长的数,利⽤字符串函数和操作运算将每⼀位数取出,存⼊数组中。
2)⾼精度数位数的确定 位数的确定:接收时往往⽤字符串,所以它的位数就等于字符串的长度 3)进位,错位处理 进位,错位处理 加法运算:c[i] = a[i] + b[i]if(c[i]>10){c[i]%10=10;++c[i+1];}减法运算: if(a[i]<b[i]){--a[i+1];a[i]+=10;}乘法运算:c[i+j-1]=a[i]*b[i]+x+c[i+j-1];x = c[i+j-1]/10;c[i+j-1]%=10;算法实现# 关于⾼精度加法#include<cstdio>#include<cstring>#include<iostream>using namespace std ;#define MAXLEN 110 // 确保长度int main(){char al[MAXLEN],bl[MAXLEN]; // 原始数字字符串// 两个加数结果加数和结果的长度进位int a[MAXLEN],b[MAXLEN],c[MAXLEN],lena,lenb,lenc,x;// 初始化memset(a,0,sizeof(a));memset(b,0,sizeof(b));memset(c,0,sizeof(c));//输⼊加数和被加数scanf("%s%s",al,bl);// 计算两个字符串的长度lena = strlen(al);lenb = strlen(bl);//加数放⼊a数组for(int i=0;i<=lena-1;i++){a[lena-i]=al[i]-'0';}//加数放⼊b数组for(int i=0;i<=lenb-1;i++){b[lenb-i]=bl[i]-'0';}lenc = 1 ;x = 0 ;while(lenc<=lena || lenc<=lenb){ // 以两者中的最⼤的那个为结束标识c[lenc] = a[lenc] + b[lenc] + x ; // 两数相加x = (c[lenc]/10) ; // 计算进位c[lenc] %= 10 ; // 本位保留的数lenc++ ;}c[lenc] = x ; // 排除⾮零问题if(c[lenc]==0){lenc--; // 处理最⾼进位}for(int i=lenc;i>=1;i--){cout<<c[i] ; // 输出结果}cout<<endl;return0 ;}//⾼精度减法#include<cstdio>#include<cstring>#include<iostream>using namespace std ;#define MAXLEN 110int main(){int a[MAXLEN],b[MAXLEN],c[MAXLEN],lena,lenb,lenc,i;char n[MAXLEN],n1[MAXLEN],n2[MAXLEN];// 初始化memset(a,0,sizeof(a));memset(b,0,sizeof(b));memset(c,0,sizeof(c));//输⼊减数和被减数scanf("%s%s",n1,n2);if(strlen(n1)<strlen(n2) || (strlen(n1)==strlen(n2)&&strcmp(n1,n2) < 0 )){ strcpy(n,n1);strcpy(n1,n2);strcpy(n2,n);cout<<"-"; // 交换了减数和被减数,结果为负数}// 计算两个字符串的长度lena = strlen(n1);lenb = strlen(n2);//被减数放⼊a数组for(int i=0;i<=lena-1;i++){a[lena-i]=n1[i]-'0';}//减数放⼊b数组for(int i=0;i<=lenb-1;i++){b[lenb-i]=n2[i]-'0';}i = 1 ;while(i<=lena || i<=lenb){ // 什么时候结束if(a[i]<b[i]){a[i]+=10; // 不够减,那么向⾼位借1当⼗a[i+1]--;}c[i] = a[i]-b[i] ; // 对应位相减i++;}lenc = i ;while((c[lenc]==0)&&(lenc>1)){lenc--; //最⾼位的 0 不输出}for(i=lenc;i>=1;i--){cout<<c[i];}cout<<endl;return0 ;}。
高精度算法大全

⾼精度算法⼤全什么是⾼精度数?在⼀般的科学计算中,会经常算到⼩数点后⼏百位或者更多,当然也可能是⼏千亿⼏百亿的⼤数字。
⼀般这类数字我们统称为⾼精度数,⾼精度算法是⽤计算机对于超⼤数据的⼀种模拟加,减,乘,除,乘⽅,阶乘,开放等运算。
对于⼀个很⼤的数字N >= 10^ 100, 很显然这样的数字⽆法在计算机中正常存储。
于是, 我们想到了办法,将这个数字拆开,拆成⼀位⼀位的或者是四位四位的存储到⼀个数组中, ⽤⼀个数组去表⽰⼀个数字。
这样这个数字就被称谓是⾼精度数。
对于⾼精度数,也要像平常数⼀样做加减乘除以及乘⽅的运算,于是就有了⾼精度算法:由于计算机输⼊计算结果的精度通常受到计算机的限制,如:在双精度⽅式下,计算机最多只能输出16位有效数字,如果超过16位,则只能按浮点形式输出,另外,⼀般计算机实数表⽰的范围为1038,如果超过这个范围,计算机就⽆法表⽰了。
但是我们可以通过⼀⼀、基本⽅法:(⼀)、数据的接收与存储要在计算机上进⾏⾼精度计算,⾸先就应该有精确的输⼊,即计算机要精确地接收和存储数据。
基本思路:1、以字符串的⽅式读⼊数字并保存在ac字符数中。
2、⽤strlen函数计算字符数组ac中总字符数(⾼精度数的位数)并保存在整型数组的a[0]中。
3、将字符串中的字符逐个字符转化成数字并保存在整型数组a中。
这⼀部分的代码编写⾮常重要,运算都会从低位开始 (先算个位,再算⼗位,再……)在存储时需要倒序存储,也就是个位数存在a[1],⼗位数存在a[2]最⾼位存在a[a[0]]。
例如数字4678在数组中存储结构为:a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9]4 8 7 6 4下⾯的程序dh⼦函数完成了以字符⽅式读⼊两个字符串并将其转化成数字存储在数组a[]和b[]中。
#include<iostream>#include<cstring>using namespace std;int a[1010],b[1010]; //⽤于存储拆解后的数字void dh(){int an,bn,i;char ac[1010],bc[1010];cin>>ac>>bc;a[0]=strlen(ac); //a⾼精度数的位数存在a[0]中for(i=1;i<=a[0];i++)a[i]=ac[a[0]-i]-'0'; //倒序存储数字(+、-\*)b[0]=strlen(bc); //b⾼精度数的位数存在b[0]中for(i=1;i<=b[0];i++)b[i]=bc[b[0]-i]-'0';//倒序存储数字(+、-\*)return;}int main(){dh();return 0;}(⼆)、运算结果的输出a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9]4 0 0 0 1 0 0 0 0 0b[0] b[1] b[2] b[3] b[4] b[5] b[6] b[7] b[8] b[9]3 9 9 9 0 0 0 0 0 0结果 1 0 0 0 0 0 0 0 0这⾥只考虑⾼精加、⾼精减、⾼精乘这类倒序存放的数据的计算结果的输出,这三类数据由于是倒序存放,⽽且运算结果的位数很难确定,如1000-999=1,如下表所⽰所以此类运算结果的输出⼀般都需要⼀个去除前导0的过程,也就是说忽略掉数组中后⾯所有的⽆效0,定位到数组中最右⼀个⾮0数字,再从最右侧的⾮0位开始依次输出数字。
高精度计算c++加法

高精度计算c++加法在计算机科学中,高精度计算是经常需要用到的一种技术,尤其是在处理大数运算时。
C语言是一种常用的编程语言,它提供了许多内置函数来处理整数,包括高精度计算。
在C语言中,可以使用长整型数据类型来进行高精度计算。
本文将介绍如何使用C语言进行高精度加法运算。
一、高精度加法原理高精度加法运算与普通的加法运算有一些不同。
在普通加法中,我们需要考虑进位的问题,而在高精度加法中,我们需要考虑的是位的数量。
也就是说,我们需要将两个大数分别表示成一位一位的形式,然后逐位相加,如果有进位,则要向上一位加。
最终得到的结果就是两个大数和的最高位以及剩下的位。
二、实现高精度加法下面是一个简单的C语言程序,用于实现高精度加法:```c#include <stdio.h>#include <stdlib.h>#define MAX_DIGITS 1000 // 定义最大位数// 高精度加法函数long long add(long long a, long long b) {long long carry = 0; // 进位初始化为0long long result[MAX_DIGITS+1]; // 结果数组,长度为最大位数+1int i, k; // i表示当前处理的位数,k表示当前位的值for (i = 0; i < MAX_DIGITS; i++) { // 处理每一位k = (int)a % 10 + (int)b % 10; // 当前位的值result[i] = k + carry; // 加上进位carry = result[i] / 10; // 计算进位result[i+1] += carry * 10; // 将进位写入下一个位置}if (carry > 0) { // 如果有进位result[MAX_DIGITS] += carry; // 将最高位的进位写入结果数组的最后一位}// 将结果数组逆序输出即可得到结果for (i = MAX_DIGITS-1; i >= 0; i--) {printf("%lld ", result[i]);}printf("\n");return result[0]; // 返回结果数组的第一个值}int main() {long long a, b, result;printf("Enter two large numbers: \n");scanf("%lld %lld", &a, &b); // 读入两个大数result = add(a, b); // 对两个数进行高精度加法运算printf("Result: %lld\n", result); // 输出结果return 0;}```这个程序中,我们首先定义了一个常量MAX_DIGITS来表示最大位数。
03.高精度计算(C++版)

printf("Input minuend:"); gets(n1); //输入被减数
printf("Input subtrahend:"); gets(n2); //输入减数
if (strlen(n1)<strlen(n2)||(strlen(n1)==strlen(n2)&&strcmp(n1,n2)<0))
gets(a1); //scanf geti
gets(b1);
//输入加数与被加数
lena=strlen(a1);
lenb=strlen(b1);
for (i=0;i<=lena-1;i++) a[lena-i]=a1[i]-48; a1[i] - ‘0’ //加数放入a数组
for (i=0;i<=lenb-1;i++) b[lenb-i]=b1[i]-48; //加数放入b数组
856 + 255 1111
图1
A3 A2 A1 + B3 B2 B1 C4 C3 C2 C1
图2
如果我们用数组A、B分别存储加数和被加数,用数组C存储结果。则上例有 A[1]=6,A[2]=5, A[3]=8,B[1]=5,B[2]=5,B[3]=2,C[4]=1,C[3]=1,C[2]=1, C[1]=1,两数相加如图2所示。
using namespace std;
int main()
{
int a[256],b[256],c[256],lena,lenb,lenc,i;
char n[256],n1[256],n2[256];
memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); memset(c,0,sizeof(c));
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
万进制高精度运算(C++语言)目前在青少年信息学奥林匹克竞赛中所涉及到的高精度计算包括加(addition)、减(subtract)、乘(multiply)、除(divide)四种基本运算。
其中乘法分高精度数乘高精度数和单精度数乘高精度数两种,除法一般指两个单精度数相除,求解最终指定精度的解,找出循环节或输出指定精度位数的小数。
(注:高精度数与单精度数均指整数)主要的解题思想是利用在小学就曾学习过的竖式加减乘除法则,用程序语言实现存在的问题主要有如何存储高精度数的值,如何实现计算等问题。
一. 高精度数字的存储我们日常书写一个高精度数字,左侧为其高位,右侧为其低位,在计算中往往会因进位(carry )或借位(borrow )导致高位增长或减少,因此我们定义一个整型数组(int bignum[maxlen])从低位向高位实现高精度整数的存储,数组的每个元素存储高精度数中的一位。
(如下表所示)高精度数 3(高位)…… 7 9 4(低位)int bignum[i]n……21显然,在C++语言中,int 类型(4个字节/32位计算机)元素存储十进制的一位数字非常浪费空间,并且运算量也非常大,因此常将程序代码优化为万进制,即数组的每个元素存储高精数字的四位。
在后面的叙述过程中均以万进制为例介绍。
(为什么选择万进制,而不选择更大的进制呢?十万进制中的最大值99999相乘时得到的值是9999800001超过4个字节的存储范围而溢出,从而导致程序计算错误。
)在实际编写程序代码过程中常作如下定义: const int base=10000; const int maxlen=1000+1; int bignum[maxlen];说明:base 表示进制为万进制,maxlen 表示高精度数的长度,1个元素能存储4个十进制位,1000个元素就存储4000个十进制位,而加1表示下标为0的元素另有它用,常用作存储当前高精度数字的位数。
二. 各种运算的程序实现 (一)加法:首先回顾一下小学中曾学习的竖式加法,见图一:bignum1[] 9475 46 1243 bignum2[]918 1324 341 carry1 0 0 0 bignum_ans[]139313701584图一 加法的计算过程从上面的图中我们可以得知,做加法运算是从低位向高位进行,如果有进位,下一位进行相加时要加上进位,如果最高位已计算完还有进位,就要增加存储结果的位数,保存起进位来。
关于进位的处理,往往定义单独变量carry 进行存储,程序实现的过程如图二所示:初始化进位carry 赋初始值0,结果的位数为两个加数的最大位数。
当前位超过最高位了?处理当前位和进位NY还有进位么?N处理进位Y图二 加法的实现过程高精度加法程序代码(bignum1+bignum2→bignum_ans ):void addition(int *bignum1, int *bignum2, int *bignum_ans){ int carry=0; memset( bignum_ans, 0, sizeof(bignum_ans) );// memset 作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法。
*bignum_ans=*bignum1>*bignu2?*bignum1:*bignum2; for(int pos=1; pos<=*bignum_ans; pos++){ carry+=bignum1[pos]+bignum2[pos]; bignum_ans[pos]=carry%base; carry/=base; } while(carry){ bignum_ans[++*bignum_ans]=carry%base; carry/=base; } }说明:函数中的数组是引用传递,传递的是数组的首元素的地址,可用指针来代替,当前指针所指向的为0元素,后面的代码相同。
有的同学可能提出,在加法运算中的进位不管进制是多少,进位只可能出现1,用while 循环没有意义,在这里说明一下,为了跟后面乘法中出现的代码相匹配才采用这种处理方法,实现代码的统一性。
(二)减法:bignum1[] 132 9475 46 1243 bignum2[] 132 918 1324 341 borrow 0 1 0 0 bignum_ans[]85568722902图三 减法的计算过程图三表示出了减法的计算过程,与加法不同的地方是进位变成了借位,另外就是计算结果的位数可能会比被减数的位数少,因此在处理过程中要更要注意结果到底是多少位的。
其次,日常我们做减法时,如果被减数小于减数,我们是把两数反过来进行相减,在前面添加负号标识。
因此,我们在编写减法子函数时是约定bignum1大于bignum2的,调用时首先判断两个高精度数的大小,然后根据两数的大小决定如何调用。
减法的实现过程如图四所示:图四 减法的实现过程高精度数比较程序代码:int bignumcmp( int *bignum1, int *bignum2 ){ if (*bignum1-*bignum2) return *bignum1-*bignum2; for (int pos=*bignum1; pos>0; pos--)初始化借位borrow 赋初始值0,结果的位数为被减数的位数。
当前位超过最高位了?处理当前位和借位NY结果高位为0?N结束结果位数减1Yif ( bignum1[pos]-bignum2[pos] ) return bignum1[pos]-bignum2[pos]; return 0;}说明:bignum1>bignum2返回正整数,bignum1==bignum2返回0,bignum1<bignum2返回负整数。
解释:首先进行两数的位数的比较,如果位数相同再从高位向低位比较。
高精度减法程序代码(bignum1-bignum2→bignum_ans ):void subtract( int *bignum1, int *bignum2, int *bignum_ans ){ int borrow=0; memset( bignum_ans, 0, sizeof(bignum_ans) ); *bignum_ans=*bignum1; for(int pos=1; pos<=*bignum_ans; pos++){ bignum_ans[pos]=bignum1[pos]-borrow-bignum2[pos]; if(bignum_ans[pos]<0){ bignum_ans[pos]+=base; borrow=1; }else{borrow=0; } } while( !bignum_ans[*bignum_ans] ) --*bignum_ans; }(三)乘法:乘法的计算过程正如图五所示的从乘数的最低位起枚举每一位与被乘数相乘,累加到结果当中。
高精度乘高精度实际是多次调用单精度数乘高精高数运算。
1 2 3 4 X 4 3 2 1 (1) 1 2 3 4 (2) 2 4 6 8 (3) 3 7 0 2 (4) 4 9 3 65332114图五 乘法的计算过程首先看一下单精度数乘高精度数的实现过程,如图六所示:初始化进位carry 赋初始值0,结果的位数被乘数的位数。
当前位超过最高位了?处理当前位和进位NY还有进位么?N结束处理进位Y图六单精度乘高精度实现过程单精度乘高精度程序代码(n*bignum→bignum_ans):void SingleMultiply(int n, int *bignum, int *bignum_ans){int carry=0;memset(bignum_ans, 0, sizeof(bignum_ans);*bignum_ans=*bignum;for(int pos=1; pos<=*bignum_ans; pos++){carry+=n*bignum[pos];bignum_ans[pos]=carry%base;carry/=base;}while(carry){bignum_ans[++*bignum_ans]=carry%base;carry/=base;}}高精度数乘高精度数,实质就是在单精度数乘高精度数的基础上枚举各个乘数位与被乘数相乘,累计到结果当中。
其中乘数中的第J位与被乘数中的第I位相乘时,结果应该保存到结果的第I+J-1位中,因为如果存在进位的问题结果的位数可能为乘数与被乘数的位数和,也可能为两者位数和减一,这一点也应该单独处理。
过程就不再展示了,具体的请阅读下面的程序代码:高精度乘高精度程序代码(bignum1*bignum2→bignum_ans):void BignumMultiply( int *bignum1, int *bignum2, int *bignum_ans){int carry=0, i, j;memset(bignum_ans, 0, sizeof(bignum_ans) );for (j=1; j<=*bignum2; j++){for(i=1; i<=*bignum1; i++){bignum_ans[i+j-1]+=carry+bignum1[i]*bignum2[j];carry=bignum_ans[i+j-1]/base;bignum_ans[i+j-1]%=base;}i=j+*bignum1;while(carry){bignum_ans[i++]=carry%base;carry/=base;}}*bignum_ans=*bignum1+*bignum2;while( !bignum_ans[*bignum_ans] ) --*bignum_ans;}(四)除法:除法在高精度计算中是最为特殊的,在近几年联赛中并没有出现类似的题目,除法类的高精度题目会涉及到精度和循环节问题,在这里首先用表格分析两个例子:例一:3除以8,结果为0.375被除数 3 30 60 40商0 . 3 7 5余数 3 6 4 0例二:45除以56,结果为0.803(571428)被除数 45 450 20 200 320 400 80 240 160 480 商 0 . 8 0357 1428余数45220 32 40 824 16 48 32在例一中展示的为能被除尽的情形,能被除尽的条件是余数为0,而在例二中56并不能除尽45,出现571428这个循环节,出现循环节的条件是当前的余数曾经出现在前面求得的余数序列中。