《2022年高中信息技術(shù) 全國青少年奧林匹克聯(lián)賽教案 多精度數(shù)值處理》由會員分享,可在線閱讀,更多相關(guān)《2022年高中信息技術(shù) 全國青少年奧林匹克聯(lián)賽教案 多精度數(shù)值處理(5頁珍藏版)》請在裝配圖網(wǎng)上搜索。
1、2022年高中信息技術(shù) 全國青少年奧林匹克聯(lián)賽教案 多精度數(shù)值處理
課題:多精度數(shù)值的處理
目標(biāo):
知識目標(biāo):多精度值的加、減、乘、除
能力目標(biāo):多精度值的處理,優(yōu)化!
重點:多精度的加、減、乘
難點:進位與借位處理
板書示意:
1) 輸入兩個正整數(shù),求它們的和
2) 輸入兩個正整數(shù),求它們的差
3) 輸入兩個正整數(shù),求它們的積
4) 輸入兩個正整數(shù),求它們的商
授課過程:
所謂多精度值處理,就是在對給定的數(shù)據(jù)范圍,用語言本身提供的數(shù)據(jù)類型無法直接進行處理(主要指加減乘除運算),而需要采用特殊的處理辦法進行??纯聪旅娴睦?。
例1 從鍵盤讀入兩個正整數(shù),求它
2、們的和。
分析:從鍵盤讀入兩個數(shù)到兩個變量中,然后用賦值語句求它們的和,輸出。但是,我們知道,在pascal語言中任何數(shù)據(jù)類型都有一定的表示范圍。而當(dāng)兩個被加數(shù)據(jù)大時,上述算法顯然不能求出精確解,因此我們需要尋求另外一種方法。在讀小學(xué)時,我們做加法都采用豎式方法,如圖1。
這樣,我們方便寫出兩個整數(shù)相加的算法。
8 5 6
+ 2 5 5
1 1 1 1
圖1
A3 A2 A1
+ B3 B2 B1
C4 C3 C2 C1
圖2
如果我們用數(shù)組A、B分別存儲加數(shù)和被加數(shù),用數(shù)組C存儲結(jié)果。則上例有
A[1]=6,
3、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,兩數(shù)相加如圖2所示。由上圖可以看出:
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;
因此,算法描述如下:
procedure add(a,b;var c);
{ a,b,c都為數(shù)組,a存儲被加數(shù),b存儲加數(shù),c存儲結(jié)果 }
var i,x:integer;
begin
i:=1
while (i<=a數(shù)組長度>0
4、) or(i<=b數(shù)組的長度) do begin
x := a[i] + b[i] + x div 10; {第i位相加并加上次的進位}
c[i] := x mod 10; {存儲第i位的值}
i := i + 1 {位置指針變量}
end
end;
通常,讀入的兩個整數(shù)用可用字符串來存儲,程序設(shè)計如下:
program exam1;
const
max=200;
var
a,b,c:array[1..max] of 0..9;
n:string;
lena,lenb,len
5、c,i,x:integer;
begin
write('Input augend:'); readln(n);
lena:=length(n); {加數(shù)放入a數(shù)組}
for i:=1 to lena do a[lena-i+1]:=ord(n[i])-ord('0');
write('Input addend:'); readln(n);
lenb:=length(n); {被加數(shù)放入b數(shù)組}
for i:=1 to lenb do b[lenb-i+1]:=ord(n[i])-ord('0');
6、
i:=1;
while (i<=lena) or(i<=lenb) do begin
x := a[i] + b[i] + x div 10; {兩數(shù)相加,然后加前次進位}
c[i] := x mod 10; {保存第i位的值}
i := i + 1
end;
if x>=10 then {處理最高進位}
begin lenc:=i;c[i]:=1 end
else lenc:=i-1;
for i:=l
7、enc downto 1 do write(c[i]); {輸出結(jié)果}
writeln
end.
例2 高精度減法。
從鍵盤讀入兩個正整數(shù),求它們的差。
分析:類似加法,可以用豎式求減法。在做減法運算時,需要注意的是:被減數(shù)必須比減數(shù)大,同時需要處理借位。
因此,可以寫出如下關(guān)系式
if a[i]
8、b,c:array[1..max] of 0..9;
n,n1,n2:string;
lena,lenb,lenc,i,x:integer;
begin
write('Input minuend:'); readln(n1);
write('Input subtrahend:'); readln(n2);
{處理被減數(shù)和減數(shù)}
if (length(n1)
9、;n1:=n2;n2:=n;
write('-') {n1
10、 x := a[i] - b[i] + 10 + x; {不考慮大小問題,先往高位借10}
c[i] := x mod 10 ; {保存第i位的值}
x := x div 10 - 1; {將高位借掉的1減去}
i := i + 1
end;
lenc:=i;
while (c[lenc]=0) and (lenc>1) do dec(lenc); {最高位的0不輸出}
for i:=lenc downto 1 do write(c[i]);
write
11、ln
end.
例3 高精度乘法。
從鍵盤讀入兩個正整數(shù),求它們的積。
分析:類似加法,可以用豎式求乘法。在做乘法運算時,同樣也有進位,同時對每一位進乘法運算時,必須進行錯位相加,如圖3, 圖4。
8 5 6
× 2 5
4 2 8 0
1 7 1 2
2 1 4 0 0
圖3
A 3 A 2 A 1
× B 3 B 2 B 1
C’4C’3 C’2 C’1
C”5C”4C”3C”2
C 6 C 5 C 4 C 3 C 2 C 1
圖4
分析C數(shù)組下標(biāo)的變化規(guī)律,可以寫出如下關(guān)系式
12、
C i = C’ i +C ”i +…
由此可見,C i跟A[i]*B[j]乘積有關(guān),跟上次的進位有關(guān),還跟原C i的值有關(guān),分析下標(biāo)規(guī)律,有
x:= A[i]*B[j]+ x DIV 10+ C[i+j-1];
C[i+j-1] := x mod 10;
類似,高精度乘法的參考程序:
program exam3;
const
max=200;
var
a,b,c:array[1..max] of 0..9;
n1,n2:string;
lena,lenb,lenc,i,j,x:integer;
begin
write('Inpu
13、t multiplier:'); readln(n1);
write('Input multiplicand:'); readln(n2);
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');
for i:=1 to lena do begin
x:=0;
14、
for j:=1 to lenb do begin {對乘數(shù)的每一位進行處理}
x := a[i]*b[j] + x div 10 + c[i+j-1]; {當(dāng)前乘積+上次乘積進位+原數(shù)}
c[i+j-1] := x mod 10;
end;
c[i+j]:= x div 10; {進位}
end;
lenc:=i+j;
while (c[lenc]=0) and (lenc>1) do dec(
15、lenc);
for i:=lenc downto 1 do write(c[i]);
writeln
end.
例4 高精度除法。
從鍵盤讀入兩個正整數(shù),求它們的商(做整除)。
分析:做除法時,每一次上商的值都在0~9,每次求得的余數(shù)連接以后的若干位得到新的被除數(shù),繼續(xù)做除法。因此,在做高精度除法時,要涉及到乘法運算和減法運算,還有移位處理。當(dāng)然,為了程序簡潔,可以避免高精度乘法,用0~9次循環(huán)減法取代得到商的值。這里,我們討論一下高精度數(shù)除以單精度數(shù)的結(jié)果,采取的方法是按位相除法。
參考程序:
program exam4;
const
16、 max=200;
var
a,c:array[1..max] of 0..9;
x,b:longint;
n1,n2:string;
lena:integer;
code,i,j:integer;
begin
write('Input dividend:'); readln(n1);
write('Input divisor:'); readln(n2);
lena:=length(n1);
for i:=1 to lena do a[i] := ord(n1[i]) - ord('0');
17、 val(n2,b,code);
{按位相除}
x:=0;
for i:=1 to lena do begin
c[i]:=(x*10+a[i]) div b;
x:=(x*10+a[i]) mod b;
end;
{顯示商}
j:=1;
while (c[j]=0) and (j