|
"Äëèííàÿ" àðèôìåòèêà
Èçâåñòíî, ÷òî àðèôìåòè÷åñêèå äåéñòâèÿ, âûïîëíÿåìûå êîìïüþòåðîì â îãðàíè÷åííîì ÷èñëå ðàçðÿäîâ, íå âñåãäà ïîçâîëÿþò ïîëó÷èòü òî÷íûé ðåçóëüòàò. Áîëåå òîãî, ìû îãðàíè÷åíû ðàçìåðîì (âåëè÷èíîé) ÷èñåë, ñ êîòîðûìè ìîæåì ðàáîòàòü. À åñëè íàì íåîáõîäèìî âûïîëíèòü àðèôìåòè÷åñêèå äåéñòâèÿ íàä î÷åíü áîëüøèìè ÷èñëàìè, íàïðèìåð,
30! = 265252859812191058636308480000000?
 òàêèõ ñëó÷àÿõ ìû ñàìè äîëæíû ïîçàáîòèòüñÿ î ïðåäñòàâëåíèè ÷èñåë â ìàøèíå è î òî÷íîì âûïîëíåíèè àðèôìåòè÷åñêèõ îïåðàöèé íàä íèìè.
×èñëà, äëÿ ïðåäñòàâëåíèÿ êîòîðûõ â ñòàíäàðòíûõ êîìïüþòåðíûõ òèïàõ äàííûõ íå õâàòàåò êîëè÷åñòâà äâîè÷íûõ ðàçðÿäîâ, íàçûâàþòñÿ "äëèííûìè". Ðåàëèçàöèÿ àðèôìåòè÷åñêèõ îïåðàöèé íàä òàêèìè "äëèííûìè" ÷èñëàìè ïîëó÷èëà íàçâàíèå "äëèííîé àðèôìåòèêè".
Îðãàíèçàöèÿ ðàáîòû ñ "äëèííûìè" ÷èñëàìè âî ìíîãîì çàâèñèò îò òîãî, êàê ìû ïðåäñòàâèì â êîìïüþòåðå ýòè ÷èñëà. "Äëèííîå" ÷èñëî ìîæíî çàïèñàòü, íàïðèìåð, ñ ïîìîùüþ ìàññèâà äåñÿòè÷íûõ öèôð, êîëè÷åñòâî ýëåìåíòîâ â òàêîì ìàññèâå ðàâíî êîëè÷åñòâó çíà÷àùèõ öèôð â "äëèííîì" ÷èñëå. Íî åñëè ìû áóäåì ðåàëèçîâûâàòü àðèôìåòè÷åñêèå îïåðàöèè íàä ýòèì ÷èñëîì, òî ðàçìåð ìàññèâà äîëæåí áûòü äîñòàòî÷íûì, ÷òîáû ðàçìåñòèòü â íåì è ðåçóëüòàò, íàïðèìåð, óìíîæåíèÿ.
Ñóùåñòâóþò è äðóãèå ïðåäñòàâëåíèÿ "äëèííûõ" ÷èñåë. Ðàññìîòðèì îäíî èç íèõ. Ïðåäñòàâèì íàøå ÷èñëî
30! = 265252859812191058636308480000000
â âèäå:
30! = 2 * (104)8 + 6525 * (104)7 + 2859 * (104) + 8121 * (104)5 + 9105 * (104)4 + 8636 * (104)3 + 3084 * (104)2 + 8000 * (104)1 + 0000 * (104)0.
Ýòî ïðåäñòàâëåíèå íàòàëêèâàåò íà ìûñëü î ìàññèâå, ïðåäñòàâëåííîì â òàáë. 1.
Òàáëèöà 1
|
Íîìåð ýëåìåíòà â ìàññèâå À |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
|
Çíà÷åíèå |
9 |
0 |
8000 |
3084 |
8636 |
9105 |
8121 |
2859 |
6525 |
2 |
Ìû ìîæåì ñ÷èòàòü, ÷òî íàøå "äëèííîå" ÷èñëî ïðåäñòàâëåíî â 10000-10 ñèñòåìå ñ÷èñëåíèÿ (äåñÿòèòûñÿ÷íî-äåñÿòè÷íàÿ ñèñòåìà ñ÷èñëåíèÿ, ïðèâåäèòå àíàëîãèþ ñ âîñüìåðè÷íî-äåñÿòè÷íîé ñèñòåìîé ñ÷èñëåíèÿ), à "öèôðàìè" ÷èñëà ÿâëÿþòñÿ ÷åòûðåõçíà÷íûå ÷èñëà.
Âîçíèêàþò âîïðîñû. ×òî çà 9 â À [0], ïî÷åìó ÷èñëî õðàíèòñÿ "çàäîì íàïåðåä"? Îòâåòû î÷åâèäíû, íî ïîäîæäåì ñ ïðåæäåâðåìåííûìè îáúÿñíåíèÿìè. Îòâåòû íà âîïðîñû áóäóò ÿñíû èç òåêñòà.
Ïðèìå÷àíèå. Ìû ðàáîòàåì ñ ïîëîæèòåëüíûìè ÷èñëàìè!
Ïåðâàÿ çàäà÷à. Ââåñòè "äëèííîå" ÷èñëî èç ôàéëà. Ðåøåíèå çàäà÷è íà÷íåì ñ îïèñàíèÿ äàííûõ.
Const MaxDig = 1000; {Ìàêñèìàëüíîå êîëè÷åñòâî öèôð — ÷åòûðåõçíà÷íûõ!}
Osn = 10000; {Îñíîâàíèå íàøåé ñèñòåìû ñ÷èñëåíèÿ,
â ýëåìåíòàõ ìàññèâà õðàíèì ÷åòûðåõçíà÷íûå ÷èñëà}
Type Tlong = Array[0..MaxDig] Of Integer;
{Ìàêñèìàëüíîå êîëè÷åñòâî äåñÿòè÷íûõ öèôð â íàøåì ÷èñëå}
Àëãîðèòì ââîäà "äëèííîãî" ÷èñëà èç ôàéëà ðàññìîòðèì íà êîíêðåòíîì ïðèìåðå.
Ïóñòü â ôàéëå çàïèñàíî ÷èñëî 23851674 è îñíîâàíèåì (Osn) ÿâëÿåòñÿ 1000 (õðàíèì ïî òðè öèôðû â ýëåìåíòå ìàññèâà À). Èçìåíåíèå çíà÷åíèé ýëåìåíòîâ ìàññèâà À â ïðîöåññå ââîäà (ïîñèìâîëüíîãî â ïåðåìåííóþ Ch) îòðàæåíî â òàáë. 2.
Òàáëèöà 2
|
À[0] |
À[1] |
À[2] |
À[3] |
Ch |
Ïðèìå÷àíèå |
|
3 |
674 |
851 |
23 |
- |
Êîíå÷íîå ñîñòîÿíèå |
|
0 |
0 |
0 |
0 |
2 |
Íà÷àëüíîå ñîñòîÿíèå |
|
1 |
2 |
0 |
0 |
3 |
1-é øàã |
|
1 |
23 |
0 |
0 |
8 |
2-é øàã |
|
1 |
238 |
0 |
0 |
5 |
3-é øàã |
|
2 |
385 |
2 |
0 |
1 |
4-é øàã: ñòàðøàÿ öèôðà ýëåìåíòà À [1] ïåðåøëà â ïîêà "ïóñòîé" ýëåìåíò À[2] |
|
2 |
851 |
23 |
0 |
6 |
5-é øàã |
|
2 |
516 |
238 |
0 |
7 |
6-é øàã |
|
3 |
167 |
385 |
2 |
4 |
7-é øàã |
|
3 |
674 |
851 |
23 |
Ïðîàíàëèçèðóåì òàáëèöó (è ïîëó÷èì îòâåòû íà ïîñòàâëåííûå âûøå âîïðîñû).
1.  À[0] õðàíèì êîëè÷åñòâî çàäåéñòâîâàííûõ (íåíóëåâûõ) ýëåìåíòîâ ìàññèâà À — ýòî óæå î÷åâèäíî.
2. Ïðè îáðàáîòêå êàæäîé î÷åðåäíîé öèôðû âõîäíîãî ÷èñëà ñòàðøàÿ öèôðà ýëåìåíòà ìàññèâà ñ íîìåðîì i ñòàíîâèòñÿ ìëàäøåé öèôðîé ÷èñëà â ýëåìåíòå i+1, à ââîäèìàÿ öèôðà áóäåò ìëàäøåé öèôðîé ÷èñëà èç À[1].  ðåçóëüòàòå ðàáîòû íàøåãî àëãîðèòìà ìû ïîëó÷èëè ÷èñëî, çàïèñàííîå "çàäîì íàïåðåä".
Ïðèìå÷àíèå (ìåòîäè÷åñêîå): Ìîæíî îãðàíè÷èòüñÿ ýòèì îáúÿñíåíèåì è ðàçðàáîòêó ïðîöåäóðû âûíåñòè íà ñàìîñòîÿòåëüíîå çàäàíèå. Ìîæíî ïðîäîëæèòü îáúÿñíåíèå. Íàïðèìåð, âûïèñàòü ôðàãìåíò òåêñòà ïðîöåäóðû ïåðåíîñ ñòàðøåé öèôðû èç A[i] â ìëàäøóþ öèôðó À[i+1], ò.å. ñäâèã óæå ââåäåííîé ÷àñòè ÷èñëà íà îäíó ïîçèöèþ âïðàâî:
For i := A[0] DownTo 1 Do
Begin
A[i+l] := A[i+l] + (Longint(A[i]) * 10) Div Osn;
A[i] := (LongInt(A[i]) * 10) Mod Osn;
End;
Ïóñòü ìû ââîäèì ÷èñëî 23851674 è ïåðâûå 6 öèôð óæå ðàçìåñòèëè "çàäîì íàïåðåä" â ìàññèâå À.  ñèìâîëüíóþ ïåðåìåííóþ ñ÷èòàëè î÷åðåäíóþ öèôðó "äëèííîãî" ÷èñëà — ýòî "7". Ïî íàøåìó àëãîðèòìó ýòà öèôðà "7" äîëæíà áûòü ðàçìåùåíà ìëàäøåé öèôðîé â À[1]. Âûïèñàííûé ôðàãìåíò ïðîãðàììû "îñâîáîæäàåò" ìåñòî äëÿ ýòîé öèôðû.  òàáëèöå îòðàæåíû ðåçóëüòàòû ðàáîòû ýòîãî ôðàãìåíòà.
|
i |
À[1] |
À[2] |
À[3] |
ch |
|
2 |
516 |
238 |
0 |
7 |
|
2 |
516 |
380 |
2 |
|
|
1 |
160 |
385 |
2 |
Ïîñëå ýòîãî îñòàåòñÿ òîëüêî äîáàâèòü òåêóùóþ (ñ÷èòàííóþ â ch) öèôðó "äëèííîãî" ÷èñëà ê À[1] è èçìåíèòü çíà÷åíèå À[0].
 êîíå÷íîì èòîãå ïðîöåäóðà äîëæíà èìåòü ñëåäóþùèé âèä:
Procedure ReadLong(Var A : Tlong);
Var ch : char; i : Integer;
Begin
FillChar(A, SizeOf(A), 0) ;
Read(ch);
While Not(ch In ['0'..'9']) Do Read(ch);
{ïðîïóñê íå öèôð âî âõîäíîì ôàéëå}
While ch In ['0'..'9'] Do
Begin
For i := A[0] DownTo 1 Do
Begin
{"ïðîòàñêèâàíèå" ñòàðøåé öèôðû â ÷èñëå èç A[i]
â ìëàäøóþ öèôðó ÷èñëà èç A[i+l]}
A[i+l] := A[i+l] + (LongInt(A[i]) * 10) Div Osn;
A[i] := (LongInt(A[i]) * 10) Mod Osn
End;
A[1] := A[l] + Ord(ch) - Ord('0');
{äîáàâëÿåì ìëàäøóþ öèôðó ê ÷èñëó èç À[1]}
If A[A[0]+1] > 0 Then Inc(A[0]);
{èçìåíÿåì äëèíó, ÷èñëî çàäåéñòâîâàííûõ ýëåìåíòîâ ìàññèâà À}
Read(ch)
End
End;
Âòîðàÿ çàäà÷à. Âûâîä "äëèííîãî" ÷èñëà â ôàéë èëè íà ýêðàí.
Êàçàëîñü áû, íåò ïðîáëåì — âûâîäè ÷èñëî çà ÷èñëîì. Îäíàêî â ñèëó âûáðàííîãî íàìè ïðåäñòàâëåíèÿ "äëèííîãî" ÷èñëà ìû äîëæíû âñåãäà ïîìíèòü, ÷òî â êàæäîì ýëåìåíòå ìàññèâà õðàíèòñÿ íå ïîñëåäîâàòåëüíîñòü öèôð "äëèííîãî" ÷èñëà, à çíà÷åíèå ÷èñëà, çàïèñàííîãî ýòèìè öèôðàìè. Ïóñòü â ýëåìåíòàõ ìàññèâà õðàíÿòñÿ ÷åòûðåõçíà÷íûå ÷èñëà. Òîãäà "äëèííîå" ÷èñëî 128400583274 áóäåò â ìàññèâå À ïðåäñòàâëåíî ñëåäóþùèì îáðàçîì:
|
A[0] |
A[1] |
A[2] |
A[3] |
|
3 |
3274 |
58 |
1284 |
Ïðè âûâîäå "äëèííîãî" ÷èñëà èç ìàññèâà íàì íåîáõîäèìî âûâåñòè 0058, èíà÷å áóäåò ïîòåðÿ öèôð. Èòàê, íåçíà÷àùèå íóëè òàêæå íåîáõîäèìî âûâîäèòü. Ïðîöåäóðà âûâîäà èìååò âèä:
Procedure WriteLong(Const A : Tlong);
Var ls, s : String; i : Integer;
Begin
Str(Osn Div 10, Is);
Write(A[A[0]]; {âûâîäèì ñòàðøèå öèôðû ÷èñëà}
For i := A[0] - l DownTo 1 Do
Begin
Str(A[i], s);
While Length(s) < Length(Is) Do s := '0' + s;
{äîïîëíÿåì íåçíà÷àùèìè íóëÿìè}
Write(s)
End;
WriteLn
End;
Òðåòüÿ çàäà÷à. Ïðåäâàðèòåëüíàÿ ðàáîòà ïî îïèñàíèþ ñïîñîáà õðàíåíèÿ, ââîäó è âûâîäó "äëèííûõ" ÷èñåë âûïîëíåíà.
Ó íàñ åñòü âñå íåîáõîäèìûå "êèðïè÷èêè", íàïðèìåð, äëÿ íàïèñàíèÿ ïðîãðàììû ñëîæåíèÿ äâóõ "äëèííûõ" ïîëîæèòåëüíûõ ÷èñåë. Èñõîäíûå ÷èñëà è ðåçóëüòàò õðàíèì â ôàéëàõ. Íàçîâåì ïðîöåäóðó ñëîæåíèÿ SumLongTwo.
Òîãäà ïðîãðàììà ââîäà äâóõ "äëèííûõ" ÷èñåë è âûâîäà ðåçóëüòàòà èõ ñëîæåíèÿ áóäåò èìåòü ñëåäóþùèé âèä:
Var A, B, C : Tlong;
Begin
Assign(Input, 'Input.txt'); Reset(Input);
ReadLong(A); ReadLong(B) ;
Close(Input);
SumLongTwo(A, B, C);
Assign(Output, 'Output.txt');
Rewrite(Output);
WriteLong(C);
Close(Output)
End.
Àëãîðèòì ïðîöåäóðû ñëîæåíèÿ ìîæíî îáúÿñíèòü íà ïðîñòîì ïðèìåðå. Ïóñòü À=870613029451, Â=3475912100517461.
|
i |
A[i] |
B[i] |
C[1] |
C[2] |
C[3] |
C[4] |
|
1 |
9451 |
7461 |
6912 |
1 |
0 |
0 |
|
2 |
1302 |
51 |
6912 |
1354 |
0 |
0 |
|
3 |
8706 |
9121 |
6912 |
1354 |
7827 |
1 |
|
4 |
0 |
3475 |
6912 |
1354 |
7827 |
3476 |
Àëãîðèòì èìèòèðóåò ïðèâû÷íîå ñëîæåíèå ñòîëáèêîì, íà÷èíàÿ ñ ìëàäøèõ ðàçðÿäîâ. È èìåííî äëÿ ïðîñòîòû ðåàëèçàöèè àðèôìåòè÷åñêèõ îïåðàöèé íàä "äëèííûìè" ÷èñëàìè èñïîëüçóåòñÿ ìàøèííîå ïðåäñòàâëåíèå "çàäîì íàïåðåä".
Ðåçóëüòàò: Ñ = 3476782713546912.
Íèæå ïðèâåäåí òåêñò ïðîöåäóðû ñëîæåíèÿ äâóõ "äëèííûõ" ÷èñåë.
Procedure SumLongTwo(A, B : Nlong; Var C : Tlong);
Var i, k : Integer;
Begin
FillChar(C, SizeOf (C), 0) ;
If A[0] > B[0] Then k := A[0] Else k : =B[0];
For i := l To k Do
Begin Ñ [i+1] := (C[i] + A[i] + B[i]) Div Osn;
C[i] := (C[i] + A[i] + B[i]) Mod Osn
{Åñòü ëè â ýòèõ îïåðàòîðàõ îøèáêà?}
End;
If C[k+l] = 0 Then C[0] := k Else C[0] := k + l
End;
×åòâåðòàÿ çàäà÷à. Ðåàëèçàöèÿ îïåðàöèé ñðàâíåíèÿ äëÿ "äëèííûõ" ÷èñåë (À=Â, À<Â, À>Â, À<=Â, À>=Â).
Function Eq(A, B : TLong) : Boolean;
Var i : Integer;
Begin
Eq := False;
If A[0] <> B[0] Then Exit
Else Begin
i := l;
While (i <= A[0]) And (A[i] = B[i]) Do Inc(i);
Eq := i = A[0] + l
End
End;
Ðåàëèçàöèÿ ôóíêöèè À >  òàêæå ïðîçðà÷íà.
Function More(A, B : Tlong) : Boolean;
Var i : Integer;
Begin If A[0] < B[0] Then More := False
Else If A[0] > B[0] Then More := True
Else Begin
i := A[0];
While (i > 0) And (A[i] = B[i]) Do Dec(i);
If i = 0 Then More := False
Else If A[i] > B[i] Then More := True
Else More:=False
End
End;
Îñòàëüíûå ôóíêöèè ðåàëèçóþòñÿ ÷åðåç ôóíêöèè Eq è More.
Function Less(A, B : Tlong) : Boolean; {A < B}
Begin
Less := Not(More(A, B) Or Eq(A, B))
End;
Function More_Eq(A, B : Tlong) : Boolean; {A >= B}
Begin
More_Eq := More(A, B) Or Eq(A, B)
End;
Function Less_Eq(A, B : Tlong) : Boolean; {A <= B}
Begin
Less_Eq := Not More(A, B)
End;
Äëÿ ñàìîñòîÿòåëüíîãî ðåøåíèÿ ìîæåò áûòü ïðåäëîæåíà ñëåäóþùàÿ, áîëåå ñëîæíàÿ, çàäà÷à. Òðåáóåòñÿ ðàçðàáîòàòü ôóíêöèþ, êîòîðàÿ âûäàåò 0, åñëè À áîëüøå Â, 1, åñëè À ìåíüøå Â, è 2 ïðè ðàâåíñòâå ÷èñåë. Íî ñðàâíåíèå äîëæíî áûòü âûïîëíåíî ñ ó÷åòîì ñäâèãà. Î ÷åì èäåò ðå÷ü? Ïîÿñíèì íà ïðèìåðå. Ïóñòü À ðàâíî 56784, à  — 634. Ïðè ñäâèãå ÷èñëà  íà 2 ïîçèöèè âëåâî ôóíêöèÿ äîëæíà ñêàçàòü, ÷òî  áîëüøå À, áåç ñäâèãà, ÷òî À áîëüøå Â. Äðóãîé ïðèìåð. Ïðè À ðàâíîì 56700, à  — 567 è ñäâèãå 2 ôóíêöèÿ äîëæíà "ñêàçàòü", ÷òî ÷èñëà ðàâíû. Ðåøåíèå ìîæåò èìåòü ñëåäóþùèé âèä:
Function More(Const À, Â : Tlong; Const sdvig : Integer) : Byte;
Var i : Integer;
Begin
If A[0] > B[0] + sdvig Then More := 0
Else
If A[0] < B[0] + sdvig Then More := l
Else Begin
i := A[0];
While (i > sdvig) And
(A[i] = B[i-sdvig]) Do Dec(i);
If i = sdvig Then Begin
More:=0;
{ñîâïàäåíèå ÷èñåë ñ ó÷åòîì ñäâèãà}
For i := 1 To sdvig Do
If A[i] > 0 Then Exit;
More := 2;
{÷èñëà ðàâíû, "õâîñò" ÷èñëà À ðàâåí íóëþ}
End
Else More := Byte(A[i] < B[i-sdvig])
End
End;
Ïÿòàÿ çàäà÷à. Óìíîæåíèå äëèííîãî ÷èñëà íà êîðîòêîå. Ïîä êîðîòêèì ïîíèìàåòñÿ öåëîå ÷èñëî òèïà LongInt.
Ïðîöåäóðà î÷åíü ïîõîäèò íà ïðîöåäóðó ñëîæåíèÿ äâóõ äëèííûõ ÷èñåë.
Procedure Mul(Const A : TLong; Const Ê : Longlnt; Var Ñ : TLong);
Var i : Integer;
{ðåçóëüòàò - çíà÷åíèå ïåðåìåííîé Ñ}
Begin
FillChar (Ñ, SizeOf(Ñ), 0);
If K = 0 Then Inc(Ñ[0]){óìíîæåíèå íà íîëü}
Else Begin
For i:= l To A[0] Do
Begin
C[i+l] := (LongInt(A[i]) * K + C[i]) Div Osn;
C[i] := (LongInt(A[i])* K + C[i]) Mod Osn
End;
If C[A[0]+1] > 0 Then C[0]:= A[0] + 1
Else C[0]:= A[0]
{îïðåäåëÿåì äëèíó ðåçóëüòàòà}
End
End;
Øåñòàÿ çàäà÷à. Âû÷èòàíèå äâóõ äëèííûõ ÷èñåë ñ ó÷åòîì ñäâèãà
Åñëè ïîíÿòèå ñäâèãà ïîêà íå ïîíÿòíî, òî îñòàâüòå åãî â ïîêîå, íà ñàìîì äåëå âû÷èòàíèå ñ ó÷åòîì ñäâèãà ïîòðåáóåòñÿ ïðè ðåàëèçàöèè îïåðàöèè äåëåíèÿ.  íà÷àëå âûÿñíèòå ëîãèêó ðàáîòû ïðîöåäóðû ïðè íóëåâîì ñäâèãå.
Ââåäåì îãðàíè÷åíèå: ÷èñëî, èç êîòîðîãî âû÷èòàþò, áîëüøå ÷èñëà, êîòîðîå âû÷èòàåòñÿ. Ðàáîòàòü ñ "äëèííûìè" îòðèöàòåëüíûìè ÷èñëàìè ìû íå óìååì.
Ïðîöåäóðà áûëà áû ïîõîæà íà ïðîöåäóðû ñëîæåíèÿ è óìíîæåíèÿ, åñëè áû íå îäíî "íî" — çàèìñòâîâàíèå åäèíèöû èç ñòàðøåãî ðàçðÿäà âìåñòî ïåðåíîñà åäèíèöû â ñòàðøèé ðàçðÿä. Íàïðèìåð, â îáû÷íîé ñèñòåìå ñ÷èñëåíèÿ ìû âû÷èòàåì 9 èç 11 — èäåò çàèìñòâîâàíèå 1 èç ðàçðÿäà äåñÿòêîâ, à åñëè èç 10000 âû÷èòàåì 9 — ïðîöåññ çàèìñòâîâàíèÿ íåñêîëüêî ñëîæíåå.
Procedure Sub (Var A : TLong; Const B : TLong; Const sp : Integer);
Var i, j : Integer;
{èç À âû÷èòàåì  ñ ó÷åòîì ñäâèãà sp, ðåçóëüòàò âû÷èòàíèÿ â À}
Begin
For i := l To B[0] Do
Begin Dec(A[i+sp], B[i]);
j: = i;{*}
{ðåàëèçàöèÿ ñëîæíîãî çàèìñòâîâàíèÿ}
while (A[j+sp] < 0) and (j <= A[0]) Do
Begin{*}
Inc(A[j+sp], Osn) ;
Dec(A[j+sp+l]); Inc(j); {*}
end; {*}
{Ðåàëèçàöèÿ ïðîñòîãî çàèìñòâîâàíèÿ.
Åñëè îïåðàòîðû, îòìå÷åííûå *, çàìåíèòü
íà íèæåïðèâåäåííûå îïåðàòîðû â ôèãóðíûõ ñêîáêàõ, òî,
ïî ïîíÿòíûì ïðè÷èíàì, ëîãèêà íå áóäåò ðàáîòàòü
ïðè âñåõ èñõîäíûõ äàííûõ. Ìîæíî ñîçíàòåëüíî ñäåëàòü
îøèáêó è ïðåäëîæèòü íàéòè åå — ïðèíöèï "îáó÷åíèå ÷åðåç îøèáêó"}
{If A[i+sp]<0 Then Begin Inc(A[i+sp], Osn);
Dec (A[i+sp+l]);End;}
End;
i := A[0];
While (i > l) And (A[i] = 0) Do Dec(i);
A[0] := i
{êîððåêòèðîâêà äëèíû ðåçóëüòàòà îïåðàöèè}
End;
Ðåêîìåíäóåòñÿ âûïîëíèòü òðàññèðîâêó ðàáîòû äàííîé ïðîöåäóðû, íàïðèìåð, äëÿ ñëåäóþùèõ èñõîäíûõ äàííûõ. ×èñëî À ðàâíî 100000001000000000000, ÷èñëî  — 2000073859998.
Ñåäüìàÿ çàäà÷à. Äåëåíèå äâóõ äëèííûõ ÷èñåë, ò.å. íàõîæäåíèå öåëîé ÷àñòè ÷àñòíîãî è îñòàòêà.
Íàïèñàòü èñõîäíóþ (áåç óòî÷íåíèé) ÷àñòü ëîãèêè íå ñîñòàâëÿåò òðóäà. Ýòî:
Procedure Long_Div_Long(Const À, Â : TLong; Var Res, Ost : TLong);
Begin
FillChar(Res, SizeOf(Res), 0); Res[0] := 1;
FillChar(Ost, SizeOf(Ost), 0); 0st[0] := 1;
Case More(A, B, 0) Of
0: MakeDel(A, B, Res, Ost);
{À áîëüøå Â, ïîêà íå çíàåì, êàê âûïîëíÿòü îïåðàöèþ - "âûíîñèì" â ïðîöåäóðó}
1: Ost:=A; {À ìåíüøå Â}
2: Res[l] := l; {À ðàâíî Â}
End;
End;
À äàëüøå? Äàëüøå íà÷èíàþòñÿ ïðîáëåìû. Äåëèòü ñòîëáèêîì íàñ íàó÷èëè â øêîëå. Íàïðèìåð,
1000143123567 |73859998
- 73859998 |----------
--------- |13541 (Öåëàÿ ÷àñòü ÷àñòíîãî)
261543143
- 221579994
----------
399631495
- 369299990
---------
303315056
- 295439992
----------
78750647
- 73859998
--------
4890649 (Îñòàòîê)
×òî ìû äåëàëè? Íà êàæäîì ýòàïå â óìå ïîäáèðàëè öèôðó (1, 3, 5 è ò.ä.), òàêóþ, ÷òî ïðîèçâåäåíèå ýòîé öèôðû íà äåëèòåëü äàåò ÷èñëî ìåíüøåå, íî íàèáîëåå áëèçêîå ê ÷èñëó... Êàêîìó? Ýòî òðóäíî ñêàçàòü ñëîâàìè, íî èç ïðèìåðà ÿñíî. Çà÷åì íàì ýòî äåëàòü â óìå, ïóñòü äåëàåò êîìïüþòåð. Îäíàêî óïðîñòèì ïðèìåð, îñòàâèì åãî äëÿ òåñòèðîâàíèÿ îêîí÷àòåëüíîé ëîãèêè ïðîöåäóðû, òåì áîëåå ÷òî è ÷èñëà "äëèííûå". Ïóñòü ÷èñëî À áóäåò ìåíüøå Â*10, òîãäà â ðåçóëüòàòå (öåëîé ÷àñòè äåëåíèÿ) áóäåò îäíà öèôðà. Íàïðèìåð, À ðàâíî 564, à  — 63 è ïðîñòàÿ äåñÿòè÷íàÿ ñèñòåìà ñ÷èñëåíèÿ. Ïîïðîáóåì ïîäîáðàòü öèôðó ðåçóëüòàòà, íî íå ìåòîäîì ïðÿìîãî ïåðåáîðà, à ìåòîäîì äåëåíèÿ îòðåçêà ïîïîëàì. Ïóñòü Down — âåðõíÿÿ ãðàíèöà èíòåðâàëà èçìåíåíèÿ ïîäáèðàåìîé öèôðû, Up — íèæíÿÿ ãðàíèöà èíòåðâàëà, Ost ðàâåí äåëèìîìó.
|
Down |
Up |
Ñ = Â * ( (Down + Up) Div 2) |
Ost = 564 |
|
0 |
10 |
315 = 63 * ( (0 + 10) Div 2) |
C < Ost |
|
5 |
10 |
441 = 63 * ( (5 + 10) Div 2) |
C < Ost |
|
7 |
10 |
504 = 63 * ( (7 + 10) Div 2) |
C < Ost |
|
8 |
10 |
567 = 63 * ( (8 + 10) Div 2) |
C > Ost |
|
8 |
9 |
504 = 63 * ( (8 + 9) Div 2) |
C < Ost |
Èòàê, ðåçóëüòàò — öåëàÿ ÷àñòü ÷àñòíîãî — ðàâåí (Up + Down) Div 2, îñòàòîê îò äåëåíèÿ — ðàçíîñòü ìåæäó çíà÷åíèÿìè Ost è Ñ. Íèæíþþ ãðàíèöó (Down) èçìåíÿåì, åñëè ðåçóëüòàò (Ñ) ìåíüøå îñòàòêà, âåðõíþþ (Up), — åñëè áîëüøå.
Óñëîæíèì ïðèìåð. Ïóñòü À ðàâíî 27856, à  — 354. Îñíîâàíèåì ñèñòåìû ñ÷èñëåíèÿ ÿâëÿåòñÿ íå 10, à 10000.
|
Down |
Up |
Ñ |
Ost = 27856 |
|
0 |
10000 |
1770000 |
C > Ost |
|
0 |
5000 |
885000 |
C > Ost |
|
0 |
2500 |
442500 |
C > Ost |
|
0 |
1250 |
221250 |
C > Ost |
|
0 |
625 |
110448 |
C > Ost |
|
0 |
312 |
55224 |
C > Ost |
|
0 |
156 |
27612 |
C < Ost |
|
78 |
156 |
41418 |
C > Ost |
|
78 |
117 |
34338 |
C > Ost |
|
78 |
97 |
30798 |
C > Ost |
|
78 |
87 |
29028 |
C > Ost |
|
78 |
82 |
28320 |
C > Ost |
|
78 |
80 |
27966 |
C > Ost |
|
78 |
79 |
27612 |
C < Ost |
Öåëàÿ ÷àñòü ÷àñòíîãî ðàâíà 78, îñòàòîê îò äåëåíèÿ — 27856 ìèíóñ 27612, ò.å. 244.
Ïîðà ïðèâîäèòü ïðîöåäóðó. Èñïîëüçóåìûå "êèðïè÷èêè": ôóíêöèÿ ñðàâíåíèÿ ÷èñåë (More) ñ ó÷åòîì ñäâèãà è ôóíêöèÿ óìíîæåíèÿ äëèííîãî ÷èñëà íà êîðîòêîå (Mul) îïèñàíû âûøå.
Function FindBin(Var Ost : Tlong; Const  : TLong; Const sp : Integer) : Longint;
Var Down, Up : Word; C : TLong;
Begin
Down := 0;Up := 0sn;
{îñíîâàíèå ñèñòåìû ñ÷èñëåíèÿ}
While Up - l > Down Do
Begin
{Åñòü âîçìîæíîñòü ïðåïîäàâàòåëþ ñäåëàòü
ñîçíàòåëüíóþ îøèáêó. Èçìåíèòü óñëîâèå
öèêëà íà Up>Down. Ðåçóëüòàò - çàöèêëèâàíèå ïðîãðàììû.}
Mul(Â, (Up + Down) Div 2, Ñ);
Case More(Ost, C, sp) Of
0: Down := (Down + Up) Div 2;
1: Up := (Up + Down) Div 2;
2: Begin Up := (Up + Down) Div 2; Down := Up End;
End;
End;
Mul(B, (Up + Down) Div 2, C);
If More (Ost, C, 0) = 0 Then Sub(Ost, C, sp)
{íàõîäèì îñòàòîê îò äåëåíèÿ}
Else begin Sub (C, Ost, sp); Ost := C end;
FindBin := (Up + Down) Div 2;
{öåëàÿ ÷àñòü ÷àñòíîãî}
End;
Îñòàëîñü ðàçîáðàòüñÿ ñî ñäâèãîì, çíà÷åíèåì ïåðåìåííîé sp â íàøåì èçëîæåíèè. Îïÿòü âåðíåìñÿ ê îáû÷íîé ñèñòåìå ñ÷èñëåíèÿ è ïîïûòàåìñÿ ðàçäåëèòü, íàïðèìåð, 635 íà 15. ×òî ìû äåëàåì? Âíà÷àëå äåëèì 63 íà 15 è ôîðìèðóåì, ïîäáèðàåì â óìå ïåðâóþ öèôðó ðåçóëüòàòà. Ïîäáèðàòü ñ ïîìîùüþ êîìïüþòåðà ìû íàó÷èëèñü. Ïîäîáðàëè — ýòî öèôðà 4, è ýòî ñòàðøàÿ öèôðà ðåçóëüòàòà. Èçìåíèì îñòàòîê. Åñëè âíà÷àëå îí áûë 635, òî ñåé÷àñ ñòàë 35. Âû÷èòàòü ñ ó÷åòîì ñäâèãà ìû óìååì. Îïÿòü ïîäáèðàåì öèôðó. Âòîðóþ öèôðó ðåçóëüòàòà. Ýòî öèôðà 2 è îñòàòîê 5. Èòàê, ðåçóëüòàò (öåëàÿ ÷àñòü) 42, îñòàòîê îò äåëåíèÿ 5. À ÷òî èçìåíèòñÿ, åñëè îñíîâàíèåì áóäåò íå 10, à 10000? Ëîãèêà ñîâïàäàåò, òîëüêî â óìå ñ÷èòàòü íåñêîëüêî òðóäíåå, íî âåäü ó íàñ æå åñòü ìîëîòîê ïîä íàçâàíèåì êîìïüþòåð — ïóñòü îí âáèâàåò ãâîçäè.
Procedure MakeDel(Const À, Â : TLong; Var Res, Ost : TLong);
Var sp : Integer;
Begin
Ost := A; {ïåðâîíà÷àëüíîå çíà÷åíèå îñòàòêà}
sp := À[0] - Â[0];
If More(À, Â, sp) = l Then Dec(sp);
{B * Osn > A, â ðåçóëüòàòå îäíà öèôðà}
Res[0] := sp + l;
While sp >= 0 Do
Begin
{íàõîäèì î÷åðåäíóþ öèôðó ðåçóëüòàòà}
Res[sp + 1] := FindBin(Ost, B, sp);
Dec(sp)
End
End;
Ìåòîäè÷åñêèå ðåêîìåíäàöèè. Ïðåäñòàâëåííûé ìàòåðèàë èçëàãàåòñÿ íà ÷åòûðåõ çàíÿòèÿõ ïî èçâåñòíîé ñõåìå: 10-15-ìèíóòíîå èçëîæåíèå èäåé, à çàòåì ðàáîòà ó÷àùèõñÿ ïîä ðóêîâîäñòâîì ïðåïîäàâàòåëÿ.
1-å çàíÿòèå. Ââîä, âûâîä è ñëîæåíèå äëèííûõ ÷èñåë (çàäà÷è 1, 2, 3).
2-å çàíÿòèå. Ôóíêöèè ñðàâíåíèÿ (çàäà÷à 4).
3-å çàíÿòèå. Óìíîæåíèå è âû÷èòàíèå äëèííûõ ÷èñåë (çàäà÷è 5, 6).
4-å çàíÿòèå. Äåëåíèå äëèííûõ ÷èñåë (çàäà÷à 7). Áåçóñëîâíî, ýòà ñõåìà íå äîãìà.  çàâèñèìîñòè îò óðîâíÿ ïîäãîòîâêè ó÷àùèõñÿ íà ñàìîñòîÿòåëüíîå âûïîëíåíèå ìîæåò áûòü âûíåñåíà çíà÷èòåëüíàÿ ÷àñòü ìàòåðèàëà. Çàìå÷ó òîëüêî, ÷òî â ñèëó ñëîæèâøåéñÿ òðàäèöèè â ðÿäå ñëó÷àåâ äîïóñêàþòñÿ ïðè èçëîæåíèè ñîçíàòåëüíûå îøèáêè.  ðåçóëüòàòå ðàáîòû êàæäûé ó÷àùèéñÿ äîëæåí èìåòü ñîáñòâåííûé ìîäóëü äëÿ ðàáîòû ñ "äëèííûìè" ÷èñëàìè.
Òåìû äëÿ èññëåäîâàíèé
1. Ðåøåíèå çàäà÷: ïîèñê íàèáîëüøåãî îáùåãî äåëèòåëÿ äâóõ "äëèííûõ" ÷èñåë; ïîèñê íàèìåíüøåãî îáùåãî êðàòíîãî äâóõ "äëèííûõ" ÷èñåë; èçâëå÷åíèå êâàäðàòíîãî êîðíÿ èç "äëèííîãî" ÷èñëà è ò.ä.
2. "Äëèííûå" ÷èñëà ìîãóò áûòü îòðèöàòåëüíûìè. Êàê èçìåíÿòñÿ îïèñàííûå âûøå îïåðàöèè äëÿ ýòîãî ñëó÷àÿ?
3. Äëÿ õðàíåíèÿ "äëèííûõ" ÷èñåë èñïîëüçóåòñÿ íå ìàññèâ, à ñòåê, ðåàëèçîâàííûé ñ ïîìîùüþ ñïèñêà. Ìîäèôèöèðîâàòü ìîäóëü ðàáîòû ñ "äëèííûìè" ÷èñëàìè.
Ñïèñîê ëèòåðàòóðû
Ñ.Ì. Îêóëîâ/ "Äëèííàÿ" àðèôìåòèêà/
Äëÿ ïîäãîòîâêè äàííîé ðàáîòû áûëè èñïîëüçîâàíû ìàòåðèàëû ñ ñàéòà http://www.comp-science.narod.ru/