高精度运算(加减)

合集下载

高精度计算(加减乘)

高精度计算(加减乘)

高精度乘高精度
× 4 1 7 2 1 8 5 2 2 8 1 2 4 0 6 5 0 0
C[5] C[4] C[3] C[2]
856 × 25 856 × 25 856 × 25 a×b[1] 856 × 25 856 × 25 856 × 25 a×b[2]
C[1] 0+0+6× 5 0 0 0 0 0 0
A3 A2 × B2 C'4 C'3 C'2 C"4 C"3 C"2 C4 C3 C2
A1 B1 C'1 C1

我们在计算高精度乘法结果时,通常先计算C'i,再加上C"i,再加上C'"i,…… Ci跟a[i]*b[j]乘积有关,跟上次的进位有关,还跟原Ci的值有关,分析下标规 律,有:
c[i+j-1]=a[i]*b[j]+x+c[i+j-1]; x=c[i+j-1]/10; c[i+j-1]%=10;
//b逐位乘数组a for (int i=1;i<=b[0];i++) { for (int j=1;j<=a[0];j++)//a逐位乘以b[i] { c[i+j-1பைடு நூலகம்=c[i+j-1]+jw+b[i]*a[j]; //数组c对应位加上进位及a、b对应位乘积 jw=c[i+j-1]/10; //处理进位 c[i+j-1]%=10; } c[i+a[0]]=jw; //a乘以b[i]后的最高位进位 } c[0]=a[0]+b[0]; while (c[0]>1&&c[c[0]]==0) c[0]--; //更新c的位数 for (int i=c[0];i>0;i--) cout<<c[i]; return 0;

高精度加减乘除算法

高精度加减乘除算法

⾼精度加减乘除算法⾼精度运算所谓的⾼精度运算,是指参与运算的数(加数,减数,因⼦……)范围⼤⼤超出了标准数据类型(整型,实型)能表⽰的范围的运算。

例如,求两个200位的数的和。

这时,就要⽤到⾼精度算法了。

在这⾥,我们先讨论⾼精度加法。

⾼精度运算主要解决以下三个问题:基本⽅法1、加数、减数、运算结果的输⼊和存储运算因⼦超出了整型、实型能表⽰的范围,肯定不能直接⽤⼀个数的形式来表⽰。

在Pascal中,能表⽰多个数的数据类型有两种:数组和字符串。

(1)数组:每个数组元素存储1位(在优化时,这⾥是⼀个重点!),有多少位就需要多少个数组元素;⽤数组表⽰数的优点:每⼀位都是数的形式,可以直接加减;运算时⾮常⽅便⽤数组表⽰数的缺点:数组不能直接输⼊;输⼊时每两位数之间必须有分隔符,不符合数值的输⼊习惯;(2)字符串:字符串的最⼤长度是255,可以表⽰255位。

⽤字符串表⽰数的优点:能直接输⼊输出,输⼊时,每两位数之间不必分隔符,符合数值的输⼊习惯;⽤字符串表⽰数的缺点:字符串中的每⼀位是⼀个字符,不能直接进⾏运算,必须先将它转化为数值再进⾏运算;运算时⾮常不⽅便;(3)因此,综合以上所述,对上⾯两种数据结构取长补短:⽤字符串读⼊数据,⽤数组存储数据:var s1,s2:string;a,b,c:array [1..260] of integer;i,l,k1,k2:integer;beginwrite('input s1:');readln(s1);write('input s2:');readln(s2);{————读⼊两个数s1,s2,都是字符串类型}l:=length(s1);{求出s1的长度,也即s1的位数;有关字符串的知识。

}k1:=260;for i:=l downto 1 dobegina[k1]:=ord(s1)-48;{将字符转成数值}k1:=k1-1;end;k1:=k1+1;{————以上将s1中的字符⼀位⼀位地转成数值并存在数组a中;低位在后(从第260位开始),⾼位在前(每存完⼀位,k1减1)}对s2的转化过程和上⾯⼀模⼀样。

C++知识点高精度

C++知识点高精度

C++知识点⾼精度⼀.⾼精度加法1.1 ⾼精度加法⾼精度运算的基本运算就是加和减。

和算数的加减规则⼀样,模拟竖式计算,考虑错位运算与进位处理。

#include <cstdio>#include <cstring>int main(){char a[202]={0}, b[202]={0};scanf("%s%s", a, b);int alen = strlen(a), blen = strlen(b), t = 0, i;int a1[202]={0}, b1[202]={0};for (i = 0; i < alen; i++) a1[i] = a[alen-1-i]-'0';for (i = 0; i < blen; i++) b1[i] = b[blen-1-i]-'0';alen = (alen > blen) ? alen : blen;for (i = 0; i <= alen; i++)t = a1[i]+b1[i], a1[i] = t%10, a1[i+1] += t/10;while (!a1[i] && i) i--;for(; i >= 0; i--) printf("%d", a1[i]);return0;}1.2 ⾼精度加法(压位)(清北学堂成果)int型可以存9位数字,⽽上述代码在数组的每个元素中只存了0-9中的⼀位数,可以说浪费了很多空间,⽽且计算机计算4+5和3333+4444⽤的时间是相同的,所以我们有时候⽤压位来节省空间和时间。

其原理如下:从键盘读⼊⼤整数并存放在字符数组中从后向前每⼋位数字存放在⼀个int型数组的⼀个元素中对两个数组的对应元素进⾏加减运算,有进位要进位,最后输出#include <iostream>#include <cstring>#include <cstdio>using namespace std;const int INF = 1E8;struct Data{int u[50], l;Data(){memset(u, 0, sizeof(u)), l = 0;}void change(string a){int len = a.size(), k = len / 8, i = 0;l = k + (len%8 > 0);for (len; len > 8; len -= 8)sscanf(a.substr(len-8, 8).c_str(), "%d", &u[i++]);if (len > 0) sscanf(a.substr(0, len).c_str(), "%d", &u[i]);}void print(){int k = l-1;printf("%d", u[k--]);while (k >= 0) printf("%8.8d", u[k--]);printf("\n");}}a, b;int main(){string aa, bb, ac;cin >> aa >> bb;int ka = 0, kb = 0, i;a.change(aa),b.change(bb);for (i = 0; i < 50; i++)a.u[i] +=b.u[i], a.u[i+1] += a.u[i] / INF, a.u[i] %= INF;for (i = 49; a.u[i]==0 && i>0; i--);a.l = i + 1;a.print();return0;}⼆.⾼精度减法2.1 ⾼精度减法原理和加法⼀样,需要不过考虑的不是进位,⽽是借位。

c++的正整数高精度加减乘除

c++的正整数高精度加减乘除

c++的正整数⾼精度加减乘除数值计算之⾼精度加减乘除⼀.⾼精度正整数的⾼精度计算1.加法2.减法减法和加法的最⼤区别在于:减法是从⾼位开始相减,⽽加法是从低位开始相加3.乘法:⽤⾼精度加法实现l 乘法的主要思想是把乘法转化为加法进⾏运算。

请先看下⾯的等式:12345*4=12345+12345+12345+1234512345*20=123450*212345*24=12345*20+12345*4l 等式(1)说明,多位数乘⼀位数,可以直接使⽤加法完成。

l 等式(2)说明,多位数乘形如d*10n的数,可以转换成多位数乘⼀位数来处理。

l 等式(3)说明,多位数乘多位数,可以转换为若⼲个“多位数乘形如d*10n的数与多位数乘⼀位数”之和。

l 因此,多位数乘多位数最终可以全部⽤加法来实现。

4.除法:⽤⾼精度减法实现⼆.注意清零和对位操作三. 代码1//2// main.cpp3// 正整数⾼精度运算4//5// Created by ashley on 14-11-9.6// Copyright (c) 2014年 ashley. All rights reserved.7//89 #include <iostream>10 #include <string>11using namespace std;1213string clearZeros(string data)14 {15if (data[0] == '0') {16int key = (int) data.length() - 1;17for (int i = 0; i < data.length(); i++) {18if (data[i] != '0') {19 key = i;20break;21 }22 }23 data.erase(0, key);24 }25if (data == "") {26 data = "0";27 }28return data;29 }3031//对位操作32void countPoint(string &operand1, string &operand2)33 {34while (operand1.length() < operand2.length()) {35 operand1 = "0" + operand1;36 }37while (operand1.length() > operand2.length()) {38 operand2 = "0" + operand2;39 }40 }4142//判断⼤⼩43bool bigger(string operand1, string operand2)44 {45return operand1 >= operand2;46 }4748string addition(string addent, string adder)49 {50//先对位,在加数和被加数前⾯适当补0,使他们包含相同的位数51 countPoint(addent, adder);52//前⾯再补⼀个0,确定和的最多位数53 addent = "0" + addent;54 adder = "0" + adder;55//从低位开始,对应位相加,结果写进被加数中,如果有进位,直接给被加数前⼀位加1 56for (int i = (int) addent.length() - 1; i > 0; i--) {57 addent[i] = addent[i] + adder[i] - 48;58if (addent[i] > '9') {59 addent[i] = addent[i] - 10;60 addent[i - 1] = addent[i - 1] + 1;61 }62 }63return clearZeros(addent);64 }6566string subtraction(string subtrahend, string subtractor)67 {68//先对位,在减数和被减数前⾯适当补0,使他们包含相同的位数69 countPoint(subtrahend, subtractor);70//判断被减数和减数谁⼤,保证被减数⼤于减数71if (bigger(subtrahend, subtractor)) {72 subtrahend[0] = subtrahend[0] - subtractor[0] + 48;73for (int i = 1; i < (int)subtrahend.length(); i++) {74if (subtrahend[i] >= subtractor[i]) {75 subtrahend[i] = subtrahend[i] - subtractor[i] + 48;76 } else {77 subtrahend[i] = subtrahend[i] - subtractor[i] + 10 + 48;78 subtrahend[i - 1]--;79 }80 }81 } else {82 subtrahend = '-' + subtraction(subtractor, subtrahend);83 }84return subtrahend;85 }8687string multiplication(string multiplicand, string multiplier)88 {89string result = "0";90for (int i = (int)multiplier.length() - 1; i >= 0 ; i--) {91for (char c = '1'; c <= multiplier[i]; c++) {92 result = addition(result, multiplicand);93 }94 multiplicand = multiplicand + "0";95 }96return clearZeros(result);97 }9899// 试商法100string division(string dividend, string divisor)101 {102// 存放商103string result;104// 存放余数105string remains;106for (int i = 0; i < (int)dividend.length(); i++) {107 remains = remains + dividend[i];108 result = result + "0";109// 从1往上试110while (bigger(remains, result)) {111 cout << result << "-----------" << remains << endl;112 result[result.length() - 1]++;113 remains = subtraction(remains, divisor);114 }115 }116return clearZeros(result);117 }118int main(int argc, const char * argv[])119 {120string a, b;121int tests;122 cin >> tests;123while (tests--) {124 cin >> a >> b;125//正整数⾼精度加法,从低位开始126//cout << addition(a, b) << endl;127//正整数⾼精度减法,从⾼位开始128//cout << subtraction(a, b) << endl;129//正整数⾼精度乘法,将乘法转换为加法进⾏运算130//cout << multiplication(a, b) << endl;131 cout << division(a, b) << endl;132//正整数⾼精度除法133134 }135return0;136 }。

高精度加减乘除 浮点型

高精度加减乘除 浮点型

高精度加减乘除浮点型
高精度加减乘除是指针对浮点数进行精确计算,避免由于浮点
数运算的精度问题而导致的计算结果不准确的情况。

在进行高精度
加减乘除浮点型计算时,需要考虑以下几个方面:
1. 精度损失,浮点数在计算机中以二进制形式表示,有时会出
现精度损失,导致计算结果不准确。

为避免这种情况,可以使用高
精度计算库,如Python中的decimal模块或者其他高精度计算库,
来进行精确计算。

2. 舍入误差,在浮点数计算过程中,舍入误差是不可避免的,
特别是在连续的加减乘除运算中。

为了减小舍入误差,可以采用四
舍五入、向上取整或向下取整等方法来处理计算结果。

3. 数值范围,浮点数的表示范围是有限的,超出范围的计算会
导致溢出或下溢。

在进行高精度计算时,需要注意数值范围的限制,避免出现计算结果超出浮点数表示范围的情况。

4. 性能考虑,高精度计算通常会牺牲一定的计算性能,因为需
要进行更复杂的运算和更多的内存存储。

在实际应用中,需要权衡
计算精度和性能之间的关系,选择合适的计算方法。

总之,高精度加减乘除浮点型计算需要综合考虑精度损失、舍入误差、数值范围和性能等多个方面的因素,以确保计算结果的准确性和可靠性。

在实际应用中,需要根据具体的计算需求选择合适的高精度计算方法和工具。

高精度运算

高精度运算

由于待处理的数据超过了任何一种数据类型所能容纳的范围,因此必须采用数串形式输入,并将其转化为数组。

该数组的每一个元素对应一个十进制数,由其下标顺序指明位序号。

由于高精度运算可能使得数据长度发生变化,因此除要用整数数组存储数据外,还需要一个整数变量纪录整数数组的元素个数,即数据的实际长度。

typenumtype=array[1..255] of byte;vara:numtype;la:byte;s:string;beginreadln(s);la:=length(s);for i:=1 to la doa[la-i+1]:=ord(s[i])-ord('0');end.高精度加法运算首先,确定a和b中的最大位数x,然后依照由低位至高位的顺序进行加法运算。

在每一次运算中,a当前位加b当前位的和除以10,其整商即为进位,其余数即为和的当前位。

在进行了x 位的加法后,若最高位有进位(a[x+1]<>0),则a的长度为x+1。

以下只列出关键程序:typenumtype=array[1..255] of word;vara,b,s:numtype;la,lb,ls:word;procedure plus(var a:numtype;var la:word;b:numtype;lb:word); {利用过程实现}vari,x:word;beginif la>=lbthen x:=laelse x:=lb;for i:=1 to x dobegina[i]:=a[i]+b[i];a[i+1]:=a[i+1]+a[i] div 10;a[i]:=a[i] mod 10;end;while a[x+1]<>0 dox:=x+1;la:=x; {最高位若有进位,则长度增加}end;高精度减法运算(a>b)依照由低位至高位的顺序进行减法运算。

在每一次位运算中,若出现不够减的情况,则向高位借位。

Pascal高精度运算(加减法)

Pascal高精度运算(加减法)

第一讲:高精度运算加减法篇类型数值范围占字节数Byte 0 .. 255 1 Word 0..65535 2 Shortint -128 .. 127 1 Integer -32768..32767; 2 Longint -2147483648 .. 2147483647 4 Longword 0..4294967295 4Int64 -9223372036854775808 ..9223372036854775807 8 QWord 0 .. 18446744073709551615 8//在竞赛学会的最新规定中由于int64在文件操作的不稳定性已经不推荐用了;而且当数据超过1020以后我们就必须要用到高精度运算•高精度运算是指参与运算有数或运算结果远远超过计算机语言中能够表示的数的范围的特殊运算。

•例如:编程解决求A+B的值,其中A,B的值<=1040;•高精度运算的思想就是运用字符串和一维数组的方式模拟运算•口诀就是:用字符串读入数据,转化数据类型,用数组存储数据,并加以运算:1、数据的输入。

2、数据的存储。

3、数据的运算:进位和借位。

4、结果的输出:小数点的位置、处理多于的0等。

加法题目要求:输入:第一行:正整数a。

第二行:正整数b。

已知:a和b(<10240)。

输出:a+b的值。

样例输入:99999样例输出:10981、数据的输入。

2、数据的存储。

3、加法运算,注意进位处理。

4、结果的输出。

a和b(<10240)字符串输入:Var s1,s2:string; Readln(s1); Readln(s2);为了计算方便,采用数组存储。

Var a,b:array[1..240] of integer;将字符串转换为数组存储。

用a存s1,b存s2。

A[1]存个位,便于以后计算和进位处理S1=’3 4 5 2 3 4 5’….a[3] a[2] a[1]len1:=length(s1);for i:= 1 to len1 do a[i]:=ord(s1[len1+1-i])-48; len2:=length(s2);for i:= 1 to len2 do b[i]:=ord(s2[len2+1-i])-48;把计算结果存到数组c中:c:array[1..241] of integer;先计算。

大数(高精度)加减乘除取模运算

大数(高精度)加减乘除取模运算

⼤数(⾼精度)加减乘除取模运算千⾟万苦找到了⼤数(⾼精度)加减乘除取模运算的算法,有的地⽅还需要再消化消化,代码先贴出来~ include <iostream>#include <string>using namespace std;inline int compare(string str1, string str2){if(str1.size() > str2.size()) //长度长的整数⼤于长度⼩的整数return 1;else if(str1.size() < str2.size())return -1;elsereturn pare(str2); //若长度相等,从头到尾按位⽐较,compare函数:相等返回0,⼤于返回1,⼩于返回-1}//⾼精度加法string ADD_INT(string str1, string str2){string MINUS_INT(string str1, string str2);int sign = 1; //sign 为符号位string str;if(str1[0] == '-') {if(str2[0] == '-') {sign = -1;str = ADD_INT(str1.erase(0, 1), str2.erase(0, 1));}else {str = MINUS_INT(str2, str1.erase(0, 1));}}else {if(str2[0] == '-')str = MINUS_INT(str1, str2.erase(0, 1));else {//把两个整数对齐,短整数前⾯加0补齐string::size_type l1, l2;int i;l1 = str1.size(); l2 = str2.size();if(l1 < l2) {for(i = 1; i <= l2 - l1; i++)str1 = "0" + str1;}else {for(i = 1; i <= l1 - l2; i++)str2 = "0" + str2;}int int1 = 0, int2 = 0; //int2 记录进位for(i = str1.size() - 1; i >= 0; i--) {int1 = (int(str1[i]) - 48 + int(str2[i]) - 48 + int2) % 10; //48 为 '0' 的ASCII 码int2 = (int(str1[i]) - 48 + int(str2[i]) - 48 +int2) / 10;str = char(int1 + 48) + str;}if(int2 != 0) str = char(int2 + 48) + str;}}//运算后处理符号位if((sign == -1) && (str[0] != '0'))str = "-" + str;return str;}//⾼精度减法string MINUS_INT(string str1, string str2){string MULTIPLY_INT(string str1, string str2);int sign = 1; //sign 为符号位string str;if(str2[0] == '-')str = ADD_INT(str1, str2.erase(0, 1));else {int res = compare(str1, str2);if(res == 0) return "0";if(res < 0) {sign = -1;string temp = str1;str1 = str2;str2 = temp;}string::size_type tempint;tempint = str1.size() - str2.size();for(int i = str2.size() - 1; i >= 0; i--) {if(str1[i + tempint] < str2[i]) {str1[i + tempint - 1] = char(int(str1[i + tempint - 1]) - 1);str = char(str1[i + tempint] - str2[i] + 58) + str;elsestr = char(str1[i + tempint] - str2[i] + 48) + str; }for(int i = tempint - 1; i >= 0; i--)str = str1[i] + str;}//去除结果中多余的前导0str.erase(0, str.find_first_not_of('0'));if(str.empty()) str = "0";if((sign == -1) && (str[0] != '0'))str = "-" + str;return str;}//⾼精度乘法string MULTIPLY_INT(string str1, string str2){int sign = 1; //sign 为符号位string str;if(str1[0] == '-') {sign *= -1;str1 = str1.erase(0, 1);}if(str2[0] == '-') {sign *= -1;str2 = str2.erase(0, 1);}int i, j;string::size_type l1, l2;l1 = str1.size(); l2 = str2.size();for(i = l2 - 1; i >= 0; i --) { //实现⼿⼯乘法string tempstr;int int1 = 0, int2 = 0, int3 = int(str2[i]) - 48;if(int3 != 0) {for(j = 1; j <= (int)(l2 - 1 - i); j++)tempstr = "0" + tempstr;for(j = l1 - 1; j >= 0; j--) {int1 = (int3 * (int(str1[j]) - 48) + int2) % 10;int2 = (int3 * (int(str1[j]) - 48) + int2) / 10;tempstr = char(int1 + 48) + tempstr;}if(int2 != 0) tempstr = char(int2 + 48) + tempstr; }str = ADD_INT(str, tempstr);}//去除结果中的前导0str.erase(0, str.find_first_not_of('0'));if(str.empty()) str = "0";if((sign == -1) && (str[0] != '0'))str = "-" + str;return str;}//⾼精度除法string DIVIDE_INT(string str1, string str2, int flag){//flag = 1时,返回商; flag = 0时,返回余数string quotient, residue; //定义商和余数int sign1 = 1, sign2 = 1;if(str2 == "0") { //判断除数是否为0quotient = "ERROR!";residue = "ERROR!";if(flag == 1) return quotient;else return residue;}if(str1 == "0") { //判断被除数是否为0quotient = "0";residue = "0";}if(str1[0] == '-') {str1 = str1.erase(0, 1);sign1 *= -1;sign2 = -1;}if(str2[0] == '-') {str2 = str2.erase(0, 1);sign1 *= -1;}int res = compare(str1, str2);if(res < 0) {quotient = "0";residue = str1;}else if(res == 0) {quotient = "1";residue = "0";string::size_type l1, l2;l1 = str1.size(); l2 = str2.size();string tempstr;tempstr.append(str1, 0, l2 - 1);//模拟⼿⼯除法for(int i = l2 - 1; i < l1; i++) {tempstr = tempstr + str1[i];for(char ch = '9'; ch >= '0'; ch --) { //试商string str;str = str + ch;if(compare(MULTIPLY_INT(str2, str), tempstr) <= 0) {quotient = quotient + ch;tempstr = MINUS_INT(tempstr, MULTIPLY_INT(str2, str)); break;}}}residue = tempstr;}//去除结果中的前导0quotient.erase(0, quotient.find_first_not_of('0'));if(quotient.empty()) quotient = "0";if((sign1 == -1) && (quotient[0] != '0'))quotient = "-" + quotient;if((sign2 == -1) && (residue[0] != '0'))residue = "-" + residue;if(flag == 1) return quotient;else return residue;}//⾼精度除法,返回商string DIV_INT(string str1, string str2){return DIVIDE_INT(str1, str2, 1);}//⾼精度除法,返回余数string MOD_INT(string str1, string str2){return DIVIDE_INT(str1, str2, 0);}int main(){char ch;string s1, s2, res;while(cin >> ch) {cin >> s1 >> s2;switch(ch) {case '+': res = ADD_INT(s1, s2); break; //⾼精度加法case '-': res = MINUS_INT(s1, s2); break; //⾼精度减法case '*': res = MULTIPLY_INT(s1, s2); break; //⾼精度乘法case '/': res = DIV_INT(s1, s2); break; //⾼精度除法, 返回商case 'm': res = MOD_INT(s1, s2); break; //⾼精度除法, 返回余数default : break;}cout << res << endl;}return(0);}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

高精度计算(一)一、教学目标●了解什么是高精度计算。

为什么要进行高精度计算。

●熟练掌握基本的加、减高精度计算二、重点难点分析●高精度数的存储方式;三、教具或课件使用多媒体演示文稿四、主要教学过程(一)引入新课利用计算机进行数值计算,有时会遇到这样的问题:有些计算要求精度高,希望计算的数的位数可达几十位甚至几百位,虽然计算机的计算精度也算较高了,但因受到硬件的限制,往往达不到实际问题所要求的精度.我们可以利用程序设计的方法去实现这们的高精度计算.这里仅介绍常用的几种高精度计算的方法。

(二)教学过程设计1、高精度计算中需要处理好以下几个问题:(1)数据的接收方法和存贮方法数据的接收和存贮:当输入的数很长时,可采用字符串方式输入,这样可输入数字很长的数,利用字符串函数和操作运算,将每一位数取出,存入数组中.Type numtype=array[1..500]of word;{整数数组类型}Var a,b:numtype;{a和b为整数数组}la,lb:integer;{整数数组a的长度和b的长度}s:string;{输入数串}将数串s转化为整数数组a的方法如下:readln(s);la:=length(s);for i:=1 to la do a[la-i+1]:=ord(s[i])-ord(‘0’);另一种方法是直接用循环加数组方法输入数据.Type arr= array[1..100] of integer;prucedure readdata(var int:arr);var ch:char;i,k:integer;beginread(ch);k:=0;while ch in['0'..'9'] do begininc(k);int[k]:=ord(ch)-ord(‘0’);read(ch);end;end;储存数据一律用数组。

根据不同的需要,数据的储存可分正向与反向两种。

以输入数1234为例:①正向储存:数位权的大小与储存数组的下标的大小一致下标大下标小数组各元素 a[4] a[3] a[2] a[1]所存的数字 1 2 3 4最高位最低位②反向储存:数位权的大小与储存数组的下标的大小相反下标小下标大数组各元素 a[1] a[2] a[3] a[4]所存的数字 1 2 3 4最高位最低位加法、减法、乘法的运算是从低位开始的,所以数据储存采取正向储存比较方便。

(2) 计算结果位数的确定①两数之和的位数最大为较大的数的位数加1。

②乘积的位数最大为两个因子的位数之和。

(3) 进位,借位处理加法进位: C[i]:= A[i]+B[i];if C[i]>=10 then begin C[i]:= C[i] mod 10; C[i+1]:= C[i+1]+1 end;减法借位: if a[i]<b[i] then begin a[i+1]:=a[i+1]-1;a[i]:=a[i]+10 endc[i]:=a[i]-b[i]乘法进位: x:= A[i]*B[j]+ x DIV 10+ C[i+j-1];C[i+j-1] := x mod 10;(4) 商和余数的求法商和余数处理:视被除数和除数的位数情况进行处理.2、高精度计算举例【例1】从键盘读入两个正整数,求它们的和。

分析:从键盘读入两个数到两个变量中,然后用赋值语句求它们的和,输出。

但是,我们知道,在pascal 语言中任何数据类型都有一定的表示范围。

而当两个被加数据大时,上述算法显然不能求出精确解,因此我们需要寻求另外一种方法。

在读小学时,我们做加法都采用竖式方法,如图1。

这样,我们方便写出两个整数相加的算法。

8 5 6+ 2 5 5---------------1 1 1 1图1如果我们用数组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所示。

A3 A2 A1+B3 B2 B1-----------------C4 C3 C2 C1图2因此,算法描述如下:procedure add(a,b;var c);{ a,b,c 都为数组,a存储被加数,b 存储加数,c 存储结果} var i,x:integer;begini:=1while (i<=a 数组长度) or(i<=b 数组的长度) do beginx := a[i] + b[i] + x div 10; {第i位相加并加上次的进位}c[i] := x mod 10; {存储第i 位的值}i := i + 1 {位置指针变量}endend;通常,读入的两个整数用可用字符串来存储,程序设计如下:program exam1;const max=200;var a,b,c:array[1..max] of 0..9;n:string;lena,lenb,lenc,i,x:integer;beginwrite(’Input augend:’); readln(n);lena:=length(n); {加数放入a 数组}for i:=1 to lena do a[lena-i+1]:=ord(n[i])-ord(’0’);write(’Input addend:’); readln(n);lenb:=length(n); {被加数放入b数组}for i:=1 to lenb do b[lenb-i+1]:=ord(n[i])-ord(’0’);i:=1;while (i<=lena) or(i<=lenb) dobeginx := a[i] + b[i] + x div 10; {两数相加,然后加前次进位}c[i] := x mod 10; {保存第i 位的值}i := i + 1end;if x>=10 then {处理最高进位}begin lenc:=i;c[i]:=1; endelse lenc:=i-1;for i:=lenc downto 1 do write(c[i]); {输出结果}writelnend.【例2】高精度减法(a-b)(a>b且a,b均为正整数)。

从键盘读入两个正整数,求它们的差。

分析:类似加法,可以用竖式求减法。

在做减法运算时,需要注意的是:被减数必须比减数大,同时需要处理借位。

高精度减法的参考程序:program exam2;constmax=200;vara,b,c:array[1..max] of 0..9;n,n1,n2:string;lena,lenb,lenc,i,x:integer;beginwrite(’Input minuend:’); readln(n1);write(’Input subtrahend:’); readln(n2); {处理被减数和减数}if (length(n1)<length(n2)) or (length(n1)=length(n2)) and (n1<n2) thenbeginn:=n1;n1:=n2;n2:=n;write(’-’) {n1<n2,结果为负数}end;lena:=length(n1); lenb:=length(n2);for i:=1 to lena do a[lena-i+1]:=ord(n1[i])-ord(’0’);for i:=1 to lenb do b[lenb-i+1]:=ord(n2[i])-ord(’0’);i:=1;while (i<=lena) or(i<=lenb) dobeginx := a[i] - b[i] + 10 + x; {不考虑大小问题,先往高位借10}c[i] := x mod 10 ; {保存第i 位的值}x := x div 10 - 1; {将高位借掉的1减去}i := i + 1end;lenc:=i;while (c[lenc]=0) and (lenc>1) do dec(lenc); {最高位的0 不输出}for i:=lenc downto 1 do write(c[i]);writelnend.【补充例题】高精度加减法,把输入的数可能有负数也考虑进去的程序。

【变量与算法设计】用两个逻辑变量f与f1。

用f1来控制运算:当f1为假做加法,当f1为真做减法。

当f为真来控制数前负号的输出。

具体设置如下:两个数同号f1为假(做加法运算)两个数都是正数,f为假两个数都是负数,f为真。

(f为真输出负号,下同)两个数异号f1为真(做减法运算)第一个为负数,第二个为正数。

第一个数的绝对值大于第二个数的绝对值。

f为真第一个为负数,第二个数正数。

第一个数的绝对值小于第二个数的绝对值。

f为假第一个数正数,第二个为负数。

第一个数的绝对值大于第二个数的绝对值。

f为假第一个为正数,第二个为负数。

第一个数的绝对值小于第二个数的绝对值。

f为真【程序清单】PROGRAM P12_10A;CONST n=200;VAR str1,str2,str:STRING;k,l1,l2,i,j,t:Integer;a,b:ARRAY [1..n] OF Integer;fa,fb:Char;f1,f:Boolean;BEGINWrite('Input a string str1 : '); Readln(str1);Write('Input a string str2 : '); Readln(str2);l1:=Length(str1); l2:=Length(str2);fa:=str1[1]; fb:=str2[1]; f1:=False; f:=f1; {取符号位,设置f1、f的值}IF (fa='-') AND (fb='-'){如都是负数,去掉符号位}THEN BEGIN{重新设置f1、f的值}f1:=False; f:=True; str1:=Copy(str1,2,l1); l1:=l1-1;str2:=Copy(str2,2,l2); l2:=l2-1 ENDELSE BEGINIF fa='-' THEN {如第一个数是负数,去掉其符号位,重新设置f1、f的值}BEGIN f1:=True; f:=f1; str1:=Copy(str1,2,l1); l1:=l1-1 END;IF fb='-' THEN{如第二个数是负数,去掉其符号位,重新设置f1、f的值}BEGIN f1:=True; f:=False; str2:=Copy(str2,2,l2); l2:=l2-1 ENDEND;j:=l1; {如第二个数的绝对值大于第一个数的绝对值就交换,重新设置f的值}IF (l2>l1) OR f1 AND (l2=l1) AND (str2>str1) THENBEGIN f:=NOT(f); j:=l2; str:=str1; str1:=str2; str2:=str END;FOR i:=length(str1) DOWNTO 1 DO BEGIN {字符串分离同时转换成数字,存入a数组} Val(str1[i],a[l1+1-i],k);{不能转换成数字时,输出出错信息}IF k>0 THEN BEGIN Writeln('Str1 data error !'); Readln; Exit ENDEND;FOR i:=length(str2) DOWNTO 1 DO BEGIN {字符串分离同时转换成数字,存入b数组} Val(str2[i],b[l2+1-i],k); {不能转换成数字时,输出出错信息}IF k>0 THEN BEGIN Writeln('Str2 data error !'); Readln; Exit ENDEND;IF f1THEN BEGIN{f1为真做减法}FOR i:=1 TO j DO BEGINa[i]:=a[i]-b[i];k:=Ord(a[i]<0);{减法借位}a[i]:=a[i]+k*10;a[i+1]:=a[i+1]-kEND;WHILE (a[j]=0) AND (j>0) DO j:=j-1{有效数字前无用的0不输出}ENDELSE BEGIN{f1为假做加法}FOR i:=1 TO j DO BEGINk:=a[i]+b[i];a[i]:=k MOD 10;{加法进位}a[i+1]:=a[i+1]+k DIV 10END;IF a[i+1]>0 THEN j:=j+1{最后一次进位}END;Write('Xiang Jia He : ');{输出}IF j=0THEN Write(0)ELSE BEGINIF f THEN Write('-'); {输出符号位}FOR i:=j DOWNTO 1 DO Write(a[i]){高精度输出}END;Writeln; ReadlnEND.3、【上机练习】1.将例1、例2中的程序用过程函数完善程序。

相关文档
最新文档