第9课 高精度运算

合集下载

高精度计算

高精度计算

高精度计算由于计算机具有运算速度快,计算精度高的特点,许多过去由人来完成的烦琐、复杂的数学计算,现在都可以由计算机来代替。

计算机计算结果的精度,通常要受到计算机硬件环境的限制。

例如,pascal 要计算的数字超过19位,计算机将按浮点形式输出;另一方面,计算机又有数的表示范围的限制,在一般的微型计算机上,实数的表示范围为l0-38 -l038。

例如,在计算N!时,当N=21时计算结果就超过了这个范围,无法计算了。

这是由计算机的硬件性质决定的,但是,我们可以通过程序设计的方法进行高精度计算(多位数计算)。

学习重点1、掌握高精度加、减、乘、除法。

3、理解高精度除法运算中被除数、除数、商和余数之间的关系。

4、能编写相应的程序,解决生活中高精度问题。

学习过程一、高精度计算的基本方法用free pascal程序进行高精度计算,首先要处理好以下几个基本问题:【数据的输入与保存】(1)一般采用字符串变量存储数据,然后用length函数测量字符串长度确定其位数。

(2)分离各位数位上的数字分离各数位上的数通常采用正向存储的方法。

以“163848192”为例,见下表:A[9] A[8] A[7] A[6] A[5] A[4] A[3] A[2] A[1]1 6 3 8 4 8 1 9 2基本原理是A[1]存放个位上的数字,A[2]存放十位上的数字,……依此类推。

即下标小的元素存低位上的数字,下标大的元素存高位上的数字,这叫“下标与位权一致”原则。

【计算结果位数的确定】(1)高精度加法:和的位数为两个加数中较大数的位数+1。

(2)高精度减法:差的位数为被减数和减数中较大数的位数。

(3)高精度乘法:积的位数为两个相乘的数的位数之和。

(4)高精度除法:商的位数按题目的要求确定。

【计算顺序与结果的输出】高精度加、减、乘法,都是从低位到高位算起,而除法相反。

输出结果都是从高位到低位的顺序,注意:高位上的零不输出(整数部分是零除外)。

高精度计算

高精度计算

高精度计算由于计算机具有运算速度快,计算精度高的特点,许多过去由人来完成的烦琐、复杂的数学计算,现在都可以由计算机来代替,人可以从计算中解放出来,做更具有创造性的工作。

计算机计算结果的精度,通常要受到计算机硬件环境的限制。

例如,QB要计算的数字超过16位,计算机将按浮点形式输出;另一方面,计算机又有数的表示范围的限制,在一般的微型计算机上,实数的表示范围为l0-38 -l038。

例如,在计算N!时,当N=34时计算结果就超过了这个范围,无法计算了。

这是由计算机的硬件性质决定的,用户一般是无法改变的。

但是,我们可以通过‖软‖的方式来解决这一困难,即通过程序设计的方法进行高精度计算。

学习重点1、掌握高精度计算基本方法并能应用。

2、掌握高精度加法、高精度减法、高精度乘法。

3、掌握高精度除法,理解高精度除法运算中被除数、除数、商和余数之间的关系。

4、分析总结常用高精度算法特点,并能编写相应的程序。

5、在学习的过程中应强化―算法领先‖的意识,根据实际情况对高精度运算进行优化的策略与方法。

学习过程一、高精度计算的基本方法在计算机上进行高精度计算,首先要处理好以下几个基本问题:【数据的接收与存储】(1)一般采用字符串变量接收数据,然后用测量字符串长度函数确定其位数。

INPUT A$L=LEN(A$)(2)分离各位数位上的数分离各数位上的数通常采用正向存储的方法。

以―163848192‖为例,见下表:A(9) A(8) A(7) A(6) A(5) A(4) A(3) A(2) A(1)1 6 3 8 4 8 3 9 2基本原理是A(1)存放个位上的数字,A(2)存放十位上的数字,……依此类推。

结合字符串中MID$可以实现各数位上数字的分离FOR I= 1 TO LA(I)=VAL(MID$(A$,L+1-I,1)NEXT I【计算结果位数的确定】(1)高精度加法的和的位数为两个加数中较大数的位数加1。

(2)高精度减法的差的位数为被减数和减数中较大数的位数加1。

高精度计算

高精度计算

数字一个一个输入,存入数组


一个正整数,把它的数字从最高位开始,一个 一个输入,直至最后一个数字,再输入一个任 意负数,表示输入结束。 每输入一个数字,就存入数组的一个元素之中。 具体操作如下:
1) 2)
3)
输入一个数字,如为负数,就结束输入; 判断此数字是否合法,合法就存入数组,不合法就显 示出错的停息,结束; 重复(1)、(2)操作。
四种基本的高精度计算


高精度加法 高精度减法 高精度乘法 高精度除法
高精度加法

高精度加法运算的算法,需要从输入、处 理和输出这三部分来分析
数据的输入与存储,估计结果的位数, 定义存储数组的大小

1)
设参与加法运算的两个数串为 a_str 和 b_str:
输入 a_str 与 b_str,计算两者的长度 La = LEN(a_str) : Lb = LEN(b_str) 比较 La 与 Lb 的大小,如 Lb 大,要交换 a_str 和b_str (同时交换La和Lb),然后定义数组: DIM as integer a(La+1), b(La+1) 两数相加,其和存放在 a() 数组中,不再开辟新的 存储单元;

一位一位取出被除数; 在除法运算中,每次都要把上一次的余数*10, 再加上取出的本位被除数 ( 与 例9 不同 ), 临时组成被除数。

具体的算法是: Y = Y * 10 + A(K) ‘A(K):被除数 D(K) = Y \ B ‘D(K):商 Y = Y MOD B ‘ 余数
循环结束时,如除不尽,余数保存在 y 中。 第一次做除法运算前,先设 Y = 0。
高精度计算的主要步骤:

高精度运算及其应用

高精度运算及其应用

高精度运算及其应用一、引言利用计算机进行数值运算,经常会遇到数值太大,超出Longint、int64等系统标准数据类型的有效范围,如计算m n,而m、n≤100;有时又会遇到对运算的精度要求特别高的情况,如计算圆周率π,要求精确到小数点后100位,此时real、double等数据类型也无能为力。

这些情况下,我们都要用“高精度运算”来解决。

一般我们将小数点后几百位或者更多,当然也可能是几千亿几百亿的大数字统称为高精度数。

高精度运算首先要解决存储问题。

一般都是定义一个一维数组来存储一个高精度数,用每一个数组元素存储该数的每一位或某几位。

高精度数的读入可以采用两种方法,一是采用字符串(String,AnsiString)方式一起读入,再逐位处理成数字存储在数组中;另一种方法是一位一位读入并存储到数组中。

在实际使用时,请大家注意比较各自的优、缺点。

高精度运算一般都是采用模拟的方法解决。

输出时一定要注意格式和精度。

二、高精度运算1、编程实现高精度加法[问题描述] 输入两个正整数(最多250位),输出它们的和。

比如输入:99999999999999999999999999999999999999999999999999999912345678999999999999999999999999输出:add=1000000000000000000000012345678999999999999999999999998[问题分析]只要模拟“加法运算”的过程,从低位(对齐)开始逐位相加,最后再统一处理进位即可。

[参考程序]Program ex1(input,output);const max=250;var s1,s2:string;a,b,c:array[1..max] of byte;l1,l2,l,i:integer;beginwriteln('input two large integer:');readln(s1);readln(s2); {用字符串方式读入两个高精度数}l1:=length(s1);l2:=length(s2);for i:=1 to max do begin a[i]:=0;b[i]:=0;c[i]:=0;end; {注意一定要初始化}for i:=1 to l1 doa[i]:=ord(s1[l1+1-i])-48;for i:=1 to l2 dob[i]:=ord(s2[l2+1-i])-48; {以上是把两个高精度数逐位处理并转存到a、b两个数组中}if l1>l2 then l:=l1 else l:=l2;for i:=1 to l do c[i]:=a[i]+b[i]; {对应位相加}for i:=1 to l do {从低位到高位,统一处理进位}if c[i]>=10 thenbeginc[i]:=c[i]-10;c[i+1]:=c[i+1]+1;end;if c[l+1]>0 then l:=l+1;write('add='); {输出}for i:=l downto 1 do write(c[i]);readln;end.[思考和练习]1、如果要一边加一边进位,程序怎么修改?你觉得好不好?2、如果输入的数再大一点,比如1000位,还好用String类型读入吗?程序怎么修改?3、请你编写一个高精度减法的程序,注意结果的正负。

高精度计算

高精度计算

高精度计算肖波由于计算机的特点是运算速度快,精确度高,因此利用计算机进行高精度的计算和处理是计算机的一个重要应用。

在信息学奥赛中经常出现需要进行高精度处理的问题。

一、数据输入先将要计算的数据输入到内存中一般是按位存到数组中,按位对齐。

定义:第一位表示个位,n表示最高位。

1、利用字符串输入:先以字符串方式输入,再存入数组。

对非法输入可以作检查,处理小数、有符号数比较方便。

2、带小数、正负号问题①利用查找函数查找小数点(.)、正负号(+、-)②记录小数点的位置和正负号。

③处理符号位。

3、位数对齐问题①无小数位对齐:以个位对齐②有小数位对齐:以小数点对齐4、存储问题①一位一存储②四位一存储二、估算结果位数高精度计算的结果位数要估算好,以便赋初值和控制循环次数。

设A、B为两个高精度数,结果为C,用L A、L B、L C分别表示A、B、C的位数。

加法:C=A+B L C=MAX(L A,L B)+1 是最长的位数加1减法:C=A-B L C=MAX(L A,L B) 是最长的位数乘法:C=A*B L C=L A+L B除法:问题比较复杂,求商、余数、小数、可以不可以除尽,精确到小数点后几位。

一般取较大的位数作为结果位数。

阶乘、乘方的位数可以用对数求出。

1、X n的位数计算由数学知识可知:一个自然数的位数基本等于这个数的常用对数取整加1。

由此可知对于X n来说它的位数为 = (int)n*log10(x) + 12、N!的位数计算N!=N×(N-1)×(N-2)……×3×2×1Log10(n!) = (int)(log10(n)+log10(n-1)+……+log10(2)+log10(1))+1三、计算和进位问题高精度计算要求自己来编写进位。

进位存放在C I中。

加法:一位存储,C I=A I+B I+C I,若C I>10,则C I=C I-10,C I+1=1四位存储,C I=A I+B I+C I,若C I>10000,则C I=C I-10000,C I+1=1减法:保证大数减小数。

高精度运算讲稿

高精度运算讲稿

第一讲PASCAL高精度运算程序所处理加工的各类数据都有相应的值域限定。

一旦某类型的数据超出了规定的范围,运算结果就会出错。

表7.1.1列举PASCAL内部设置的几种标准类型,其中实数single、duble、comp和extended为浮点数类型,必须在程序前通过编译命令{$n+}启动浮点数运算表7.1.1但是在有些试题中,变量运算对象的数值范围是任何数据类型所无法容纳的,因此人们不得不采用数串形式,并将其转化为整数数组,其中每个元素对应一位数,由其下标顺序指明位序号。

运算规则如同算术运算。

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

vara,b:array[1..250]of word; { 整数数组} la,lb:integer;{a,b数组的长度}s:string;{数串}⑴将数串转换为整数数组按照由左而右的顺序,数串由高位到低位;而在整数数组中,则按照下标递减的顺序排列,即s i对应的数字(ord(s i)-ord(‘0’))应存入a[la-i+1](或b[lb-i+1])读数串s;la←length(s);for i:=1 to la do a[la-i+1]←ord(s i)-ord(‘0’);读数串s;lb←length(s);for i:=1 to lb do b[lb-i+1]←ord(s i)-ord(‘0’);⑵加法运算(a←a+b(a和b为整数数组)首先确定两数中的最大位数x=max{la,lb},然后从a和b的第1位出发,依照由低位至高位的顺序逐位相加,共进行x次加法运算。

在每一次位运算中,a当前位加b当前位的和除以10,其整商即为进位,其余数即为和的当前位:procedure plus(var a:numtype;b:numtype); {a←a+b} vari,x:byte;beginif la≥lb then x←la {确定两数中的最大位数} else x←lb;for i←1 to x do {逐位相加} begina[i] ←a[i]+b[i];a[i+1] ←a[i+1]+a[i] div 10;a[i] ←a[i] mod 10end;{for}while a[la+1]≠0 do la←la+1 {和的最高位进位} end;(3)、减法运算a←a-b(a、b为numtype类型,a>b)依照由低位至高位(第1位至第la位)的顺序进行减法运算。

高精度运算

高精度运算

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

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

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

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)依照由低位至高位的顺序进行减法运算。

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

9.高精度计算

9.高精度计算

4、参考程序 、
int main(void) { int i, j; int len1,len2; int a[MAX_LEN+10],b[MAX_LEN+10],c[MAX_LEN*2+10]; char str1[MAX_LEN+10],str2[MAX_LEN+10]; for(i=0;i<MAX_LEN+10;i++) a[i]=b[i]=0; for(i=0;i<MAX_LEN*2+10;i++) c[i]=0; gets(str1); //按字符串形式读入第一个整数 按字符串形式读入第一个整数 gets(str2); len1=strlen(str1); for(j=0,i=len1-1; i>=0; i--)//把数字倒过来 把数字倒过来 a[j++]=str1[i]-'0'; len2=strlen(str2); for(j=0,i=len2-1; i>=0; i--)//倒转第二个整数 倒转第二个整数 b[j++]=str2[i]-'0';
2/33
问题描述
输出要求 一行,即相加后的结果。结果里不能有多余的前导0, 一行,即相加后的结果。结果里不能有多余的前导 , 即如果结果是342,那么就不能 即如果结果是 , 输出为0342。 输出为 。 输入样例 22222222222222222222 33333333333333333333 输出样例 Output Sample: 55555555555555555555
4、参考程序 、
}
6/33
大整数乘法
1、链接地址 、
/problem?id=2980

高精度运算

高精度运算

加法运算a←a+b(a a←a+b(a、 numtype类型 类型) 加法运算a←a+b(a、b为numtype类型)
procedure plus(var a:numtype;b:numtype);{a←a+b} var i,x:byte; begin if la>=lb then x←la{确定两数中的最大位数} else x←lb; for i←1 to x do{逐位相加} begin a[i] ←a[i]+b[i];a[i+1] ←a[i+1]+a[i] div 10;a[i] ←a[i] mod 10 end;{for} while a[x+1]<>0 do x←x+1;{和的最高位进位} la←x+1; end;{ plus }
Pascal中数据类型
整数类型: 整数类型: Shortint : -128..127 Longint:-2147483648 .. 2147483647,即:-231..231-1 即 integer:-32768..32767 Byte : 0..255, 1B Word : 0..65535, 2B,即0..216-1 即 Longword:0..4294967295,即:0..232-1 即 Int64:-9223372036854775808.. 9223372036854775807,即:-263..263-1 即 Qword:0..18446744073709551615,即0..264-1 即 Boolean (ByteBool) : false .. true ,1B Char : 0..255,1B
program plx; const e=500; var a,d,x:array[0..e] of integer; n,m,t:integer; begin write('input n,m:'); read(n,m); writeln(n,'/',m,'='); a[0]:=n;d[0]:=n div m; x[0]:=n mod m; write(d[0],'.'); for t:=1 to e do begin if x[t-1]=0 then exit; a[t]:=x[t-1]*10; d[t]:=a[t] div m; write(d[t]); x[t]:=a[t] mod m; end; end.

高精度运算s

高精度运算s

高精度运算?
所谓的高精度运算,是指在某些试题中,参与处理 的数据大小超出了标准数据类型所能表示的范围的 运算。 高精度运算是信息学奥赛中用到的最基础的知识之 一,单独考察的情形很少出现,但作为基础知识, 在考察其他主要算法时会经常用到,且常出现在难 度较高的题目中,并因其处理时的高复杂度,使许 多选手望而却步。 高精度运算对选手的编程技巧和程序调试能力提出 了很高的要求,并要求选手非常细心的去对待他。
总结
整型和实型,都是有限的范围; 程序所处理的各类型数据必有相应的值域限定。 如果待处理的数据很大,就如引例中一样,位数达到 几十甚至上千位,大大超出了所定义标准类型规定的 范围,此时结果就会出错。这是由现有计算机的软硬 件条件限制所决定的。 那么如何解决这个问题呢? 可在程序设计中使用高精度运算。
3、加法计算与进位
分析发现,实际上高精度加法运算的过程,就是模拟 手工加法竖式运算的过程。
1 2 3 4 + 5 6 7 8
①运算顺序:两运算数右对齐;从低位向高位运算; ②运算规则:同一位的两个数相加再加上从低位来的进位, 成为该位的和;这个和去掉向高位的进位就成为该位的值;
-----------6 9 1 2
数值处理
数值处理是计算机的主要功能之一。 中学信息技术课本提到:计算机具有的特点 运算速度快 计算精度高 存储能力强 利用这一特点,可以进行大数据或高精确度数的处理。
Pascal语言中的数值型数据类型
整型
类型 Byte Shortint Integer 0..255 -128..127 -32768..32767 值域 长度(字节) 1 1 2
常见的高精度运算:
加法运算 减法运算 乘法运算 除法运算
高精度运算涉及到的主要操作:

高精度计算(C版PPT培训课件

高精度计算(C版PPT培训课件

C语言数据类型
总结词
C语言有多种数据类型,包括基本数据类型 和派生数据类型。
详细描述
基本数据类型包括整型(int)、字符型 (char)、浮点型(float、double)等。 派生数据类型包括数组、结构体、联合、枚 举等,允许用户自定义数据结构。
C语言运算符
总结词
C语言支持多种运算符,包括算术运算符、关系运算符、逻辑运算符等。
高精度计算(C语言版)培训课 件
目录
• 高精度计算概述 • C语言基础 • 高精度计算在C语言中的实现 • 高精度计算的应用实例 • 高精度计算的性能优化 • 高精度计算的发展趋势和展望
01
高精度计算概述
高精度计算的背景和意义
高精度计算在科学计算、金融、工程 等领域具有广泛的应用,能够解决大 规模数值计算问题,提高计算精度和 可靠性。
04
高精度计算的应用实例
大数分解质因数
总结词
通过高精度计算,能够快速准确地分解大数 的质因数,有助于解决一些数学问题。
详细描述
高精度计算可以处理大整数,利用高精度算 法,可以快速地分解大数的质因数。这对于 密码学、数论等领域的研究具有重要意义, 例如在加密算法、数论检验等方面有广泛应
用。
求解高精度方程
优化
在快速幂算法中,可以通过预计算和缓存部分中间结果来减少重复计算,提高算法效率。
矩阵乘法
01
矩阵乘法
矩阵乘法是一种基本的线性代数 运算,可以通过两个矩阵相乘得 到一个新的矩阵。
02
03
算法步骤
优化
首先将两个矩阵按照对应元素相 乘,然后将得到的值相加得到新 的矩阵的元素。
在矩阵乘法中,可以采用分块处 理和压缩存储等技术来提高算法 效率。

高精度运算(加减)

高精度运算(加减)

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

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

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

(二)教学过程设计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;储存数据一律用数组。

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

高精度四则运算

高精度四则运算

高精度四则运算
高精度除法: 1. 将被除数和除数从高位开始逐位相除,将每一位的结果保存在一个新的数组中。 2. 需要注意的是,如果被除数小于除数Байду номын сангаас则需要向高位借位。 3. 最后将得到的结果进行逆序输出即可。
需要注意的是,在进行高精度运算时,需要考虑到进位和借位的情况,以及结果的正负号 等特殊情况。
高精度四则运算
高精度减法: 1. 将被减数和减数从低位开始逐位相减,将每一位的结果保存在一个新的数组中。 2. 需要注意的是,如果减数大于被减数,则需要向高位借位。 3. 最后将得到的结果进行逆序输出即可。
高精度乘法: 1. 将两个大整数从低位开始逐位相乘,将每一位的结果保存在一个新的数组中。 2. 需要注意的是,相乘的结果可能会超过10,需要进行进位。 3. 最后将得到的结果进行逆序输出即可。
高精度四则运算
高精度四则运算是指在计算过程中保持数值的精度,避免因计算过程中的截断误差而导致 结果不准确的问题。在计算机中,通常使用字符串或数组来表示大整数,通过模拟手工计算 的过程进行运算。
高精度加法: 1. 将两个大整数从低位开始逐位相加,将每一位的结果保存在一个新的数组中。 2. 需要注意的是,如果相加的两个位数之和超过了9,则需要进位。 3. 最后将得到的结果进行逆序输出即可。

高精度除法讲解

高精度除法讲解

高精度除法讲解
高精度除法是指对于大整数进行除法运算时,采用高精度计算的方法,以保证计算精度和正确性。

其核心思路是将大整数按照一定的位数进行分段计算,然后依次进行除法操作,最终将结果拼接起来得到最终答案。

具体实现时,可以采用类似手算除法的方法,即从被除数的高位向低位依次取数,与除数进行比较,计算出商和余数,并将余数向下一位传递。

如果被除数的位数不足以进行除法运算,则在高位添加0,直到两数位数相等。

最终得到的商即为所求的答案。

需要注意的是,在进行高精度除法时,需要对除数为0的情况进行特殊处理,一般可返回错误或抛出异常。

另外,为了提高计算效率,可以采用一些优化算法,如对被除数进行预处理、对除数进行快速幂运算等。

总之,高精度除法是一种常用的大整数计算方法,适用于需要保证计算精度和正确性的场合,如密码学、高精度计算等领域。

- 1 -。

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

高精度运算所谓的高精度运算,是指参与运算的数(加数,减数,因子……)范围大大超出了标准数据类型(整型,实型)能表示的范围的运算。

比如:求两个200位的数的和。

这时,就要用到高精度算法了。

高精度运算主要解决以下三个问题:运算结果的输入和存储、运算过程、运算结果的输出【高精度加法】1、运算结果的输入和存储运算因子超出了整型、实型能表示的范围,肯定不能直接用一个数的形式来表示。

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

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

用字符串表示数的优点:能直接输入输出,输入时,每两位数之间不必分隔符,符合数值的输入习惯;用字符串表示数的缺点:字符串中的每一位是一个字符,不能直接进行运算,必须先将它转化为数值再进行运算,运算时非常不方便;因此,我们可以综合起来考虑,对上面两种数据结构取长补短:用字符串读入数据,用数组存储数据:vars1,s2:string;a,b,c:array [1..260] of integer;i,lc,k1,k2:integer;beginwrite('input s1:');readln(s1);write('input s2:');readln(s2); {读入两个数s1,s2,都是字符串类型}lc:=length(s1); {求出s1的长度,也即s1的位数}k1:=260;for i:=lc downto 1 dobegina[k1]:=ord(s1[i])-48; {将字符转成数值,ord(‘0’)的值为48}k1:=k1-1;end;k1:=k1+1;{以上将s1中的字符一位一位地转成数值并存在数组a中,低位在后(从第260位开始),高位在前(每存完一位,k1减1)}对s2的转化过程和上面一模一样。

lc:=length(s2); {求出s2的长度,也即s2的位数}k2:=260;for i:=lc downto 1 dobegina[k2]:=ord(s2[i])-48; {将字符转成数值,ord(‘0’)的值为48}k2:=k2-1;end;k2:=k2+1;2、运算过程在往下看之前,大家先列竖式计算35+86。

注意的问题:(1)运算顺序:两个数靠右对齐;从低位向高位运算;先计算低位再计算高位;(2)运算规则:同一位的两个数相加再加上从低位来的进位,成为该位的和;这个和去掉向高位的进位就成为该位的值;如上例:3+8+1=12,向前一位进1,本位的值是2;可借助MOD、DIV运算完成这一步;(3)最后一位的进位:如果完成两个数的相加后,进位位值不为0,则应添加一位;(4)如果两个加数位数不一样多,则按位数多的一个进行计算;if k1>k2 {k1和k2分别是最高位的下标,所以小的应该更长} then k:=k2else k:=k1;y:=0;for i:=260 downto k dobeginx:=a[i]+b[i]+y;c[i]:=x mod 10; {计算当前位上的数}y:=x div 10; {计算进位}end;if y<>0 {判断最后有没有进位}then begink:=k-1;c[k]:=y;end;3、结果的输出(这也是优化的一个重点)按运算结果的实际位数输出for i:=k to 260 dowrite(c[i]);writeln;求两个数的加法的完整程序:program sum;vars1,s2:string;a,b,c:array [1..260] of integer;i,lc,k1,k2,x,y:integer;beginwrite('input s1:');readln(s1); write('input s2:');readln(s2); lc:=length(s1);k1:=260;for i:=lc downto 1 dobegina[k1]:=ord(s1[i])-48;k1:=k1-1;end;k1:=k1+1;lc:=length(s2);k2:=260;for i:=lc downto 1 dobeginb[k2]:=ord(s2[i])-48;k2:=k2-1;end;k2:=k2+1;if k1>k2then k:=k2else k:=k1;y:=0;for i:=260 downto k dobeginx:=a[i]+b[i]+y;c[i]:=x mod 10;y:=x div 10;end;if y<>0then begink:=k-1;c[k]:=y;end;for i:=k to 260 dowrite(c[i]); writeln;end.优化:以上的方法有明显的缺点:(1)浪费空间:一个整型变量(-32768~32767)只存放一位(0~9);(2)浪费时间:一次加减只处理一位;针对以上问题,我们做如下优化:一个数组元素存放四位数;(integer的最大范围是32767,5位的话可能导致出界)。

具体方法:lc:=length(s1);k1:=260;repeat {有关字符串的知识}s:=copy(s1,lc-3,4); {取s1中第lc-3个字符开始的4个字符置于s中}(lc小于3时lc-3=0)val(s,a[k1],code); {将字符串s转换成整数或实数存于a[k1]中,若s中有非法字符,则k1:=k1-1; code存放非法字符在s中的下标;否则,code为零。

code应定义为整型} s1:=copy(s1,1,lc-4); {取s1中第1个字符开始的l-4个字符置于s1中,此句的作用是lc:=lc-4; 避免取字符串的开始字符时出错} until lc<=0;k1:=k1+1;因为这个改进,算法要相应改变:(1)运算时:不再逢十进位,而是逢万进位(x mod 10000; x div 10000);(2)输出时:最高位直接输出,其余各位要判断是否足够4位,不足部分要补0;例如:1,23,2345这样三段的数,输出时,应该是100232345,而不是1234567。

改进后的算法:program sum;vars1,s2:string;a,b,c:array [1..260] of integer;i,lc,x,y,k,k1,k2,code:integer;beginwrite('input s1:');readln(s1);write('input s2:');readln(s2);lc:=length(s1);k1:=260;repeat {将s1中每四位作为一个整体取出放入数组元素中}s:=copy(s1,lc-3,4);val(s,a[k1],code);k1:=k1-1;s1:=copy(s1,1,lc-4);lc:=lc-4;until lc<=0;k1:=k1+1;lc:=length(s2);k2:=260;repeat {将s2中每四位作为一个整体取出放入数组元素中} s:=copy(s2,lc-3,4);val(s,b[k2],code);k2:=k2-1;s2:=copy(s2,1,lc-4);lc:=lc-4;until lc<=0;k2:=k2+1;if k1<k2then k:=k1else k:=k2;y:=0;for i:=260 downto k dobeginx:=a[i]+b[i]+y;c[i]:=x mod 10000;y:=x div 10000;end;if y<>0then begink:=k-1;c[k]:=y;end;write(c[k]); {最高位直接输出}for i:=k+1 to 260 do {后面各位均应满足4位输出}beginif c[i]<1000 then write('0'); {小于4位加一个0}if c[i]<100 then write('0'); {小于3位再加一个0}if c[i]<10 then write('0'); {小于2位再加一个0}write(c[i]);end;writeln;end.【高精度减法】1、和高精度加法相比,减法在差为负数时处理的细节更多一点:当被减数小于减数时,差为负数,差的绝对值是减数减去被减数;在程序实现上用一个变量来存储符号位,用另一个数组存差的绝对值。

2、算法流程:(1)读入被减数S1,S2(字符串);(2)置符号位:判断被减数是否大于减数:大则将符号位置为空;小则将符号位置为“-”,交换减数与被减数;▲如何判断被减数与减数的大小:字符串知识首先将两个字符串的位数补成一样(因为字符串的比较是从左边对齐的;两个字符串一样长才能真正地比较出大小):短的在左边补0k1:=length(s1);k2:=length(s2);if k1>k2then for i:=1 to k1-k2 dos2:='0'+s2else for i:=1 to k2-k1 dos1:='0'+s1;接着比较大小:直接比较字符串大小fh:='';if s1<s2then beginfh:='-';s:=s1;s1:=s2;s2:=s;end; {s1存被减数,符号存符号}(3)被减数与减数处理成数值,放在数组中;▲将字符串处理成数值:lc:=length(s1); {将s1处理成数值放于数组a中}k1:=260;repeats:=copy(s1,lc-3,4); {取s1中第lc-3个字符开始的4个字符置于s中}val(s,a[k1],code); {将字符串s转换成整数或实数存于a[k1]中}k1:=k1-1;s1:=copy(s1,1,lc-4); {取s1中第1个字符开始的lc-4个字符置于s1中} lc:=lc-4;until lc<=0;k1:=k1+1;lc:=length(s2); {将s2处理成数值放于数组b中}k2:=260;repeats:=copy(s2,lc-3,4); {取s1中第l-3个字符开始的4个字符置于s中}val(s,a[k2],code); {将字符串s转换成整数或实数存于a[k1]中}k2:=k2-1;s2:=copy(s2,1,lc-4); {取s1中第1个字符开始的l-4个字符置于s1中}lc:=lc-4;until lc<=0;k2:=k2+1;(4)运算:(减法跟加法比较,减法退位处理跟加法进位处理不一样)A、取数;B、判断是否需要借位;C、减,将运算结果放到差数组相应位中;D、判断是否运算完成:是,输出结果;不是,转A;处理借位:跟加法一样,在for语句外面将借位清零,循环中先用被减数减去借位。

相关文档
最新文档