Вы находитесь на странице: 1из 8

Algorithmes de multiplication de nombres entiers

stocks sous forme de chanes de caractres.


Les algorithmes dcrits ci-dessous ont t invents par Jakow Trachtenberg, n le 17 juin 1888 Odessa en
Russie. Ils ont t dvelopps et mis au point pendant sa captivit dans un camp de concentration allemand
lors de la 2me guerre mondiale, et ceci sans papier ni crayon. Aprs son vasion, Trachtenberg approfondira
ses ides en Suisse.

Le grand avantage de ces algorithmes est qu'ils peuvent s'appliquer simplement des nombres stocks sous
forme de chanes de caractres. Partant de l, il est possible manipuler de trs grands nombres (de 255 chiffres
en TP).

x N multipli par x

chaque chiffre est multipli par 2 ( partir du chiffre des units et ajout au report ventuel).
Ex : 175 * 2 = ?
2 5*2=10 donne 0 comme chiffre le plus droite et un report de 1
7*2=14 augment du report de 1 fournit 15 et donc le chiffre 5 et un report de 1
1*2=2 augment du report fournit le chiffre 3
La rponse est : 350

* le chiffre le plus droite dans la rponse est 10 moins le chiffre le plus droite dans le nombre de
dpart doubl et augment de 5 s'il est impair;
* chaque chiffre intermdiaire vaut 9 diminu du chiffre correspondant dans le nombre de dpart
doubl puis augment de la moiti de son voisin de droite et augment de 5 si le chiffre est impair;
* le chiffre le plus gauche dans la rponse est la moiti du chiffre le plus gauche dans le nombre de
dpart diminu de 2.
3
Ex : 1275 * 3 = ?
(10-5)*2=10 augment de 5 puisque le dernier chiffre (5) est impair. On obtient donc 5 avec un report de 1
(9-7)*2+[5/2]=6 augment du report de 1 et de 5 car 7 est impair. On obtient donc 2 et un report de 1
(9-2)*2+[7/2]=17 plus le report de 1. On obtient donc 8 et un report de 1
(9-1)*2+[2/2]=17 augment du report de 1 et de 5 car 1 est impair. On obtient donc 3 et un report de 2
[1/2]-2=-2 plus le report de 2 fournit 0.
La rponse est : 03825

* le chiffre le plus droite dans la rponse est 10 moins le chiffre le plus droite dans le nombre de
dpart doubl et augment de 5 s'il est impair;
* chaque chiffre intermdiaire vaut 9 diminu du chiffre correspondant dans le nombre de dpart
augment de la moiti de son voisin de droite et augment de 5 si le chiffre est impair;
* le chiffre le plus gauche dans la rponse est la moiti du chiffre le plus gauche dans le nombre de
dpart diminu de 1.
4
Ex : 1275 * 4 = ?
(10-5)=5 augment de 5 puisque le dernier chiffre (5) est impair. On obtient donc 0 avec un report de 1
(9-7)+[5/2]=4 augment du report de 1 et de 5 car 7 est impair. On obtient donc 0 et un report de 1
(9-2)+[7/2]=10 plus le report de 1. On obtient donc 1 et un report de 1
(9-1)+[2/2]=9 augment du report de 1 et de 5 car 1 est impair. On obtient donc 5 et un report de 1
[1/2]-1=-1 plus le report de 1 fournit 0.
La rponse est : 05100

5 * complter le nombre par un '0' en 1re position;


* le chiffre le plus droite dans la rponse est 0 si le chiffre le plus droite dans le nombre de dpart
est pair sinon il vaut 5;
* chaque chiffre intermdiaire vaut la moiti de son voisin de droite et augment de 5 si le chiffre est
impair;
Ex : 1275 * 5 = ?
Le premier chiffre vaut 5 puisque 5 est impair
[5/2]=2 augment de 5 car 7 est impair. On obtient donc 7
[7/2]=3 On obtient donc 3 et un report de 1
[2/2]=1 augment de 5 car 1 est impair. On obtient donc 6
[1/2]=0 On obtient donc 0
La rponse est : 06375

* complter le nombre par un '0' en 1re position;


* le chiffre le plus droite dans la rponse est le chiffre le plus droite dans le nombre de dpart
augment de 5 s'il est impair;
* chaque chiffre intermdiaire vaut le chiffre correspondant dans le nombre de dpart augment de la
moiti de son voisin de droite et augment de 5 si le chiffre est impair;
6 Ex : 1275 * 6 = ?
5 augment de 5 puisque le dernier chiffre est impair. On obtient donc 0 et un report de 1
7+[5/2]=9 augment du report de 1 et de 5 car 7 est impair. On obtient donc 5 et un report de 1
2+[7/2]=5 plus le report de 1. On obtient donc 6
1+[2/2]=2 augment de 5 car 1 est impair. On obtient donc 7
0+[1/2]=0 On obtient donc 0
La rponse est : 7650

* le chiffre le plus droite dans la rponse est le chiffre le plus droite dans le nombre de dpart
doubl et augment de 5 s'il est impair.
* chaque chiffre intermdiaire vaut le double du chiffre correspondant dans le nombre de dpart
augment de la moiti de son voisin de droite et augment de 5 si le chiffre est impair.
* le chiffre le plus gauche dans la rponse est la moiti du chiffre le plus gauche dans le nombre de
dpart.
7
Ex : 1275 * 7 = ?
5*2=10 augment de 5 puisque le dernier chiffre (5) est impair. On obtient donc 5 avec un report de 1
7*2+[5/2]=16 augment du report de 1 et de 5 car 7 est impair. On obtient donc 2 et un report de 2
2*2+[7/2]=7 plus le report de 2. On obtient donc 9
1*2+[2/2]=3 augment de 5 car 1 est impair. On obtient donc 8
[1/2]=0 fournit 0.
La rponse est : 08925

* le chiffre le plus droite dans la rponse est 10 moins le chiffre le plus droite dans le nombre de
dpart doubl;
* chaque chiffre intermdiaire vaut 9 diminu du chiffre correspondant dans le nombre de dpart
doubl puis augment de son voisin de droite;
* le chiffre le plus gauche dans la rponse est le chiffre le plus gauche dans le nombre de dpart
diminu de 2.
8
Ex : 1275 * 8 = ?
(10-5)*2=10 On obtient donc 0 avec un report de 1
(9-7)*2+5=9 augment du report de 1. On obtient donc 0 et un report de 1
(9-2)*2+7=21 augment du report. On obtient donc 2 et un report de 2
(9-1)*2+2=18 augment du report. On obtient donc 0 et un report de 2
1-2=-1 plus le report de 2 fournit 1.
La rponse est : 10200

9 * le chiffre le plus droite dans la rponse est 10 moins le chiffre le plus droite dans le nombre de
dpart;
* Chaque chiffre intermdiaire vaut 9 diminu du chiffre correspondant dans le nombre de dpart
augment de son voisin de droite;
* le chiffre le plus gauche dans la rponse est le chiffre le plus gauche dans le nombre de dpart
diminu de 1.
Ex : 1275 * 9 = ?
10-5=5 On obtient donc 5
(9-7)+5=7 On obtient donc 7
(9-2)+7=14 On obtient donc 4 et un report de 1
(9-1)+2=10 augment du report de 1. On obtient donc 1 et un report de 1
1-1=0 plus le report de 1 fournit 1.
La rponse est : 11475

* le chiffre le plus droite dans la rponse est 0;


10 * chaque chiffre intermdiaire est le voisin de droite;
* le chiffre le plus gauche dans la rponse est le chiffre le plus gauche dans le nombre de dpart.

* le chiffre le plus droite dans la rponse est le chiffre le plus droite dans le nombre de dpart;
* chaque chiffre intermdiaire vaut le chiffre correspondant dans le nombre de dpart augment de son
11
voisin de droite
* le chiffre le plus gauche dans la rponse est le chiffre le plus gauche dans le nombre de dpart.

Le programme Pascal ci-dessous pourrait tre amlior en terme de nombre de lignes. Je ne l'ai pas
optimis, voulant rester proche de l'algorithme pour gagner en lisibilit. Il contient aussi des
fonctions pour ajouter, soustraire et multiplier n'importe quels nombres entiers stocks sous forme
de chanes de caractres.

PROGRAM Trachtenberg;

USES CRT;

FUNCTION Char2Byte(C:CHAR):BYTE;(* Transforme un caractre en byte *)


BEGIN
Char2Byte:=POS(C,'0123456789')-1;
END;

FUNCTION Byte2Char(i:BYTE):CHAR;(* Transforme un byte en caractre *)


VAR Chiffres:STRING[10];
BEGIN
Chiffres:='0123456789';
IF i>9 THEN Byte2Char:='?'
ELSE Byte2Char:=Chiffres[i+1];
END;

FUNCTION Add(S1,S2:STRING):STRING;(* Ajoute les 2 nombres *)


VAR L1,L2,k,Report,i:BYTE;
S:STRING;
BEGIN
L1:=LENGTH(S1);L2:=LENGTH(S2);
IF L1>L2 THEN FOR i:=L2 TO L1-1 DO S2:='0'+S2
ELSE FOR i:=L1 TO L2-1 DO S1:='0'+S1;
L1:=LENGTH(S1);
Report:=0;
S:='';
FOR i:=L1 DOWNTO 1 DO
BEGIN
k:=Char2Byte(S1[i])+Char2Byte(S2[i])+Report;
S:=Byte2Char(k MOD 10)+S;
Report:=k DIV 10;
END;
S:=Byte2Char(Report)+S;
IF S[1]='0' THEN DELETE(S,1,1);
Add:=S;
END;

FUNCTION Soust(S1,S2:STRING):STRING;(* Soustrait les 2 nombres *)


VAR L1,L2,Report,i:BYTE;
k:SHORTINT;
S:STRING;
BEGIN
L1:=LENGTH(S1);L2:=LENGTH(S2);
IF L1>L2 THEN FOR i:=L2 TO L1-1 DO S2:='0'+S2
ELSE FOR i:=L1 TO L2-1 DO S1:='0'+S1;
L1:=LENGTH(S1);
Report:=0;
S:='';
FOR i:=L1 DOWNTO 1 DO
BEGIN
k:=Char2Byte(S1[i])-Char2Byte(S2[i])+Report;
Report:=0;
WHILE k<0 DO
BEGIN
k:=k+10;
Report:=Report-1;
END;
S:=Byte2Char(k)+S;
END;
IF S[1]='0' THEN DELETE(S,1,1);
Soust:=S;
END;

FUNCTION Mul2(S:STRING):STRING;(* Multiplie le nombre par 2 *)


VAR S2:STRING;
Report,i,j,j2,k:BYTE;
BEGIN
S2:='';
Report:=0;
FOR i:=LENGTH(S) DOWNTO 1 DO
BEGIN
k:=Char2Byte(S[i])*2;
S2:=Byte2Char(Report+k MOD 10)+S2;
Report:=k DIV 10;
END;
S2:=Byte2Char(Report)+S2;
IF S2[1]='0' THEN DELETE(S2,1,1);
Mul2:=S2;
END;

FUNCTION Mul3(S:STRING):STRING;(* Multiplie le nombre par 3 *)


VAR S2:STRING;
Report,i,j,j2,k:BYTE;
BEGIN
S2:='';
j:=Char2Byte(S[LENGTH(S)]);
k:=2*(10-j);
IF j MOD 2=1 THEN k:=k+5;
Report:=k DIV 10;
k:=k MOD 10;
S2:=Byte2Char(k)+S2;
FOR i:=LENGTH(S)-1 DOWNTO 1 DO
BEGIN
j:=Char2Byte(S[i]);
j2:=Char2Byte(S[i+1]);
k:=(9-j)*2+j2 DIV 2+Report;
IF j MOD 2=1 THEN k:=k+5;
Report:=k DIV 10;
k:=k MOD 10;
S2:=Byte2Char(k)+S2;
END;
j:=Char2Byte(S[1]);
k:=j DIV 2-2+Report;
S2:=Byte2Char(k)+S2;
IF S2[1]='0' THEN DELETE(S2,1,1);
Mul3:=S2;
END;

FUNCTION Mul4(S:STRING):STRING;(* Multiplie le nombre par 4 *)


VAR S2:STRING;
Report,i,j,j2,k:BYTE;
BEGIN
S2:='';
j:=Char2Byte(S[LENGTH(S)]);
k:=10-j;
IF j MOD 2=1 THEN k:=k+5;
Report:=k DIV 10;
k:=k MOD 10;
S2:=Byte2Char(k)+S2;
FOR i:=LENGTH(S)-1 DOWNTO 1 DO
BEGIN
j:=Char2Byte(S[i]);
j2:=Char2Byte(S[i+1]);
k:=9-j+j2 DIV 2+Report;
IF j MOD 2=1 THEN k:=k+5;
Report:=k DIV 10;
k:=k MOD 10;
S2:=Byte2Char(k)+S2;
END;
j:=Char2Byte(S[1]);
k:=j DIV 2-1+Report;
S2:=Byte2Char(k)+S2;
IF S2[1]='0' THEN DELETE(S2,1,1);
Mul4:=S2;
END;

FUNCTION Mul5(S:STRING):STRING;(* Multiplie le nombre par 5 *)


VAR S2:STRING;
Report,i,j,j2,k:BYTE;
BEGIN
S2:='';
S:='0'+S;
j:=Char2Byte(S[LENGTH(S)]);
IF j MOD 2=1 THEN S2:='5'
ELSE S2:='0';
Report:=0;
FOR i:=LENGTH(S)-1 DOWNTO 1 DO
BEGIN
j:=Char2Byte(S[i]);
j2:=Char2Byte(S[i+1]);
k:=j2 DIV 2+Report;
IF j MOD 2=1 THEN k:=k+5;
Report:=k DIV 10;
k:=k MOD 10;
S2:=Byte2Char(k)+S2;
END;
IF S2[1]='0' THEN DELETE(S2,1,1);
Mul5:=S2;
END;

FUNCTION Mul6(S:STRING):STRING;(* Multiplie le nombre par 6 *)


VAR S2:STRING;
Report,i,j,j2,k:BYTE;
BEGIN
S2:='';
S:='0'+S;
j:=Char2Byte(S[LENGTH(S)]);
IF j MOD 2=1 THEN k:=j+5
ELSE k:=j;
Report:=k DIV 10;
k:=k MOD 10;
S2:=Byte2Char(k)+S2;
FOR i:=LENGTH(S)-1 DOWNTO 1 DO
BEGIN
j:=Char2Byte(S[i]);
j2:=Char2Byte(S[i+1]);
k:=j+j2 DIV 2+Report;
IF j MOD 2=1 THEN k:=k+5;
Report:=k DIV 10;
k:=k MOD 10;
S2:=Byte2Char(k)+S2;
END;
IF S2[1]='0' THEN DELETE(S2,1,1);
Mul6:=S2;
END;

FUNCTION Mul7(S:STRING):STRING;(* Multiplie le nombre par 7 *)


VAR S2:STRING;
Report,i,j,j2,k:BYTE;
BEGIN
S2:='';
S:='0'+S;
j:=Char2Byte(S[LENGTH(S)]);
IF j MOD 2=1 THEN k:=2*j+5
ELSE k:=2*j;
Report:=k DIV 10;
k:=k MOD 10;
S2:=Byte2Char(k)+S2;
FOR i:=LENGTH(S)-1 DOWNTO 1 DO
BEGIN
j:=Char2Byte(S[i]);
j2:=Char2Byte(S[i+1]);
k:=2*j+j2 DIV 2+Report;
IF j MOD 2=1 THEN k:=k+5;
Report:=k DIV 10;
k:=k MOD 10;
S2:=Byte2Char(k)+S2;
END;
IF S2[1]='0' THEN DELETE(S2,1,1);
Mul7:=S2;
END;

FUNCTION Mul8(S:STRING):STRING;(* Multiplie le nombre par 8 *)


VAR S2:STRING;
Report,i,j,j2,k:BYTE;
BEGIN
S2:='';
k:=20-2*Char2Byte(S[LENGTH(S)]);
Report:=k DIV 10;
k:=k MOD 10;
S2:=Byte2Char(k)+S2;
FOR i:=LENGTH(S)-1 DOWNTO 1 DO
BEGIN
j:=Char2Byte(S[i]);
j2:=Char2Byte(S[i+1]);
k:=(9-j)*2+j2+Report;
Report:=k DIV 10;
k:=k MOD 10;
S2:=Byte2Char(k)+S2;
END;
j:=Char2Byte(S[1]);
k:=j-2+Report;
S2:=Byte2Char(k)+S2;
IF S2[1]='0' THEN DELETE(S2,1,1);
Mul8:=S2;
END;

FUNCTION Mul9(S:STRING):STRING;(* Multiplie le nombre par 9 *)


VAR S2:STRING;
Report,i,j,j2,k:BYTE;
BEGIN
S2:='';
k:=10-Char2Byte(S[LENGTH(S)]);
Report:=k DIV 10;
k:=k MOD 10;
S2:=Byte2Char(k)+S2;
FOR i:=LENGTH(S)-1 DOWNTO 1 DO
BEGIN
j:=Char2Byte(S[i]);
j2:=Char2Byte(S[i+1]);
k:=(9-j)+j2+Report;
Report:=k DIV 10;
k:=k MOD 10;
S2:=Byte2Char(k)+S2;
END;
j:=Char2Byte(S[1]);
k:=j-1+Report;
S2:=Byte2Char(k)+S2;
IF S2[1]='0' THEN DELETE(S2,1,1);
Mul9:=S2;
END;

FUNCTION Mul10(S:STRING):STRING;(* Multiplie le nombre par 10 *)


BEGIN
Mul10:=S+'0';
END;

PROCEDURE Swap(VAR S1,S2:STRING);(* Inverse les 2 chanes *)


VAR Tmp:STRING;
BEGIN
Tmp:=S1;
S1:=S2;
S2:=Tmp
END;

FUNCTION Multi(C:CHAR;S:STRING):STRING;(* Multiplie le nombre par un 'chiffre' *)


BEGIN
CASE C OF
'0': Multi:='0';
'1': Multi:=S;
'2': Multi:=Mul2(S);
'3': Multi:=Mul3(S);
'4': Multi:=Mul4(S);
'5': Multi:=Mul5(S);
'6': Multi:=Mul6(S);
'7': Multi:=Mul7(S);
'8': Multi:=Mul8(S);
'9': Multi:=Mul9(S);
END;
END;

FUNCTION Mult(S1,S2:STRING):STRING;(* Multiplie 2 nombres *)


VAR S,S0:STRING;
i:BYTE;
BEGIN
IF LENGTH(S1)>LENGTH(S2) THEN Swap(S1,S2);(* S1 est la chane la plus courte *)
S:='';S0:='';
FOR i:=LENGTH(S1) DOWNTO 1 DO
BEGIN
S:=Add(S,Multi(S1[i],S2)+S0);
S0:=S0+'0';
END;
Mult:=S
END;

VAR S,S1,S2:STRING;

BEGIN
CLRSCR;
WRITE('Nbre=');READLN(S);
WRITELN(S,' * 2 = ',Mul2(S));
WRITELN(S,' * 3 = ',Mul3(S));
WRITELN(S,' * 4 = ',Mul4(S));
WRITELN(S,' * 5 = ',Mul5(S));
WRITELN(S,' * 6 = ',Mul6(S));
WRITELN(S,' * 7 = ',Mul7(S));
WRITELN(S,' * 8 = ',Mul8(S));
WRITELN(S,' * 9 = ',Mul9(S));
WRITELN(Mul2(S)+' + '+Mul8(S)+' = ',Add(Mul2(S),Mul8(S)));
S1:='1234';S2:='903';
WRITELN(S1+' * '+S2+' = ',Mult(S1,S2));
WRITELN(Mul7(S)+' - '+Mul2(S)+' = ',Soust(Mul7(S),Mul2(S)));
END.

Page prcdente.
Page d'accueil.

Вам также может понравиться