Division entière

Ici, on fait dans le petit, le LCD qui déchire sa race, on y cause même calculatrices quand on est en manque !

Modérateur : Politburo

Répondre
Avatar de l’utilisateur
Pocket
Administrateur
Administrateur
Messages : 5813
Inscription : 24 mai 2002 16:55
Localisation : Toulouse
Contact :

Division entière

Message par Pocket » 12 juil. 2011 17:24

Salut,

J'ai besoin pour un projet, d'effectuer des divisions de nombre entiers le plus rapidement possible (ie avec le moins d'itérations possible) en utilisant prioritairement les opérations simple (addition, soustraction, décalage de bits) et si possible sans utiliser la multiplication. Je n'ai besoin que du quotient, le reste ne m'étant pas utile.

Si vous avez des algos, je suis preneur. [edit : il s'agit si j'ai bien compris, de la division euclidienne]

En attendant, je vais chercher sur gougoule. ;)

A+
Pocket, voit tout, sait tout, lit l'avenir dans les entrailles d'une base phpBB ...
Image

Avatar de l’utilisateur
badaze
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 7462
Inscription : 12 févr. 2007 19:36
Localisation : Pas très loin de Lyon
Contact :

Re: Division entière

Message par badaze » 12 juil. 2011 18:19

Un algo tout con

Code : Tout sélectionner

?->A
?->B
0->I
Lbl 1
A-B->C
C<=0=>Goto 3
I+1->I
A-B->A
Goto 1
Lbl 3
I->Q
A->R
Q est le quotient et R le reste.
Tout est bon dans le pocket.
Moi j'aime tout.... Casio, HP, Sharp, TI et les autres sauf que les TI semblent ne pas m'aimer :(
http://www.emmella.fr
Mes Casio - HP - Sharp - TI
Homme invisible.

Okinawok
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 413
Inscription : 12 avr. 2011 15:07

Re: Division entière

Message par Okinawok » 12 juil. 2011 19:01

Pocket tu donnes toi même une idée avec le décalage de bit.
Un algo est de déterminer la décomposition binaire du quotient.
Prenons 100 / 7 par exemple :
7 est-il plus grand que 100 ? Non ...
14...
28 ..
56 ..
112 est_il plus grand que 100 ? Oui donc le quotient se décompose en 2 puissance 3 plus d'autres puissance de 2 que l'on détermine en réitirant le procédé sur 100-56 soit 44.
Finalement on obtient que Q=2 puiss 3 + 2 puiss 2 + 2 puiss 1

Pour éviter d'utiliser la multiplication, il faut stocker une table des puissances de 2 ou la construire au fur et à mesure.

On peut redire la m^me chose en parlant bit : on décale le dénominateur vers la gauche jusqu'à ce qu'on obtienne un nombre plus grand que le numérateur ... on soustrait, on réitère .

Je sais c'est pas clair mais je dois doucher ma fille.

A+

Avatar de l’utilisateur
gege
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 7180
Inscription : 31 janv. 2008 15:24
Localisation : Banlieue Paârisienne
Contact :

Re: Division entière

Message par gege » 12 juil. 2011 19:15

Quelle taille les nombres ?
Si ils sont très grands, il existe un algorithme efficace basé sur la transformée de Fourier.
Sinon il existe une méthode qui ressemble à un algorithme de Newton, sans division...
Wouaf wouaf cherche gege cherche !!
Amusant
G.E.

Avatar de l’utilisateur
Pocket
Administrateur
Administrateur
Messages : 5813
Inscription : 24 mai 2002 16:55
Localisation : Toulouse
Contact :

Re: Division entière

Message par Pocket » 12 juil. 2011 21:06

Salut,
badaze a écrit :Un algo tout con
Oui, mais ça va faire trop d'itérations.
Okinawok a écrit :Pocket tu donnes toi même une idée avec le décalage de bit.
Oui, j'ai trouvé un truc similaire dans wikipédia :
http://fr.wikipedia.org/wiki/Division_e ... de_binaire
Je vais voir si je peux partir sur cet algorithme, avec éventuellement des multiplications effectuée de cette manière :
http://fr.wikipedia.org/wiki/Technique_ ... te_antique
gege a écrit :Quelle taille les nombres ?
36 bits divisé par 16 bits.

A+
Pocket, voit tout, sait tout, lit l'avenir dans les entrailles d'une base phpBB ...
Image

Avatar de l’utilisateur
C.Ret
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 2483
Inscription : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: Division entière

Message par C.Ret » 13 juil. 2011 00:21

Pocket a écrit :36 bits divisé par 16 bits.
Comme on connait par avance la taille maximale des deux nombres, on peut donc efficacement utiliser la méthode de la division binaire par dichotomie, et se passant de la première phase, à savoir que l'on a pas nécessairement à déterminer la borne supérieure du diviseur, elle sera quoi qu'il arrive inférieure à 36.

Prenons un exemple : divisons X par Y
#CE4D3A5D6_h divisé par #9672_h

Les deux bornes initiales sont a=0 et b=36
Etape 1.1 : la dichotomie m’incite donc à tester d = (a+b)/2 = 36/2 = 18
Je décale donc Y de 18 bit vers la gauche : on obtient #259C80000_h
Or #259C80000_h est plus petit que #CE4D3A5D6_h donc 18 est un minorant.
Les nouvelles bornes sont donc a= 18 et b = 36.

Etape1.2 : on utilise à nouveau la dichotomie : d = (18+36)/2 = 27.
Je décale donc Y de 27 bit vers la gauche (soit un décalage de 9 bits supplémentaires vers la gauche par rapport à l’étape précédente).
On obtient #4B 390000000_h qui est est plus grand que #CE4D3A5D6_h, (d’ailleurs on dépasse les 36bits soit #FFFFFFFFF_h ) c’est unpoint à surveiller en fonction des capacité de calculs du processeur.
Donc 27 est un majorant strict.
Les nouvelles bornes sont donc a=18 et b = 27

Etape n°1.3 : dichotomie : d = (18+27)/2 = 22, décalage de 22 bits (soit 4 de moins).
On obtient #25 9C800000_h qui est toujours plus grand que X (ou que la limite des 36 bits d’ailleurs).
Donc 22 est un majorant strict, le nouvel intervalle est donc a = 18 et b = 22. Il fait plus d’une unité, je continue donc.

Etape n°1.4 : dichotomie : d = (18 +22)/2 = 20, décalage de 20 bits (soit deux de moins que précèdemment). On obtient cette fois un nombre de 36bits ; #967200000_h que l’on compare avec X = #CE4D3A5D6_h qui est le plus grand. Donc 20 est un minorant. Les bornes sont donc a=20 et b=22.
On continue.

Etape n°1.5 : dichotomie d =(20 + 22)/2 = 21, décalage global de 21 bits, soit un décalage vers la droite de la valeur actuelle. On obtient #1 2CE400000_h qui est plus grand que X (et plus de 36bits). Donc 21 est un majorant strict. L’intervalle est donc réduit à a=20 et b=21.

On arrête donc là cette première phase de dichotomie car l’intervalle est unitaire.
On a donc déterminé le bit de point fort du quotient :
Q = # 0001?????_h
On retire donc Y.2^20 à X :
#CE4D3A5D6_h - #967200000_h = # 37DB3A5D6_h qui devient le nouveau dividende. Le diviseur étant toujours Y = # 9672_h.

Pour cette seconde phase, les bornes de l’intervalle sont a= 0 et b = 20. Et oui, on sait déjà que le nouveau dividende (qui est en fait le reste de la première phase) est inférieur à Y.2^20 !).

Code : Tout sélectionner

Etape   Interv   d      X                 shifted Y           Q  
                       #CE4D3A5D6_h      #     9672_h 
1.1      0 36   18 18+ #CE4D3A5D6_h      #259C80000_h  <         
1.2     18 36   27  9+ #CE4D3A5D6_h    4B#390000000_h  >> overflw
1.3     18 27   22  5- #CE4D3A5D6_h     2#59C800000_h  >> overflw
1.4     18 22   20  2- #CE4D3A5D6_h      #967200000_h  <         
1.5     20 22   21  1+ #CE4D3A5D6_h     1#2CE400000_h  >> overflw

        20 21   20  1- #37DB3A5D6_h      #967200000_h             #0001?????_h

2.1      0 20   10 10- #37DB3A5D6_h      #  259C800_h  <          
2.2     10 20   15  5+ #37DB3A5D6_h      # 4B390000_h  <          
2.3     15 20   17  2+ #37DB3A5D6_h      #12CE40000_h  <          
2.4     17 20   18  1+ #37DB3A5D6_h      #259C80000_h  <          
2.5     18 20   19  1+ #37DB3A5D6_h      #4B3900000_h  >          

        18 19   18  1- #123EBA5D6_h      #259C80000_h             #00014????_h

3.1      0 18    9     #123EBA5D6_h      #  12CE400_h  < 
3.2      9 18   13  4+ #123EBA5D6_h      # 12CE4000_h  < 
3.3     13 18   15  2+ #123EBA5D6_h      # 4B390000_h  < 
3.4     15 18   16  1+ #123EBA5D6_h      # 96720000_h  < 
3.5     16 18   17  1+ #123EBA5D6_h      #12CE40000_h  > 

        16 17   16  1- # 8D79A5D6_h      # 96720000_h             #00015????_h

4.1      0 16    8     # 8D79A5D6_h      #   967200_h  < 
4.2      8 16   12  4+ # 8D79A5D6_h      #  9672000_h  < 
4.3     12 16   14  2+ # 8D79A5D6_h      # 259C8000_h  < 
4.4     14 16   15  1+ # 8D79A5D6_h      # 4B390000_h  < 

        15 16   15  1+ # 4240A5D6_h      # 4B390000_h             #000158???_h

5.1      0 15    7     # 4240A5D6_h      #   4B3900_h  < 
5.2      7 15   11  4+ # 4240A5D6_h      #  4B39000_h  < 
5.3     11 15   13  2+ # 4240A5D6_h      # 12CE4000_h  < 
5.4     13 15   14  1+ # 4240A5D6_h      # 259C8000_h  < 

        14 15   14     # 1CA425D6_h      # 259C8000_h             #00015C???_h

6.1      0 14    7  7- # 1CA425D6_h      #   4B3900_h  <
6.2      7 14   10  3+ # 1CA425D6_h      #  259C800_h  <
6.3     10 14   12  2+ # 1CA425D6_h      #  9672000_h  <
6.3     12 14   13  1+ # 1CA425D6_h      # 12CE4000_h  <

        13 14   13     #  9D5E5D6_h      # 12CE4000_h            #00015E???_h

7.1      0 13    7  6- #  9D5E5D6_h      #   4B3900_h  < 
7.2      7 13   10  3+ #  9D5E5D6_h      #  259C800_h  < 
7.3     10 13   11  1+ #  9D5E5D6_h      #  4B39000_h  < 
7.4     11 13   12  1+ #  9D5E5D6_h      #  9672000_h  < 

        12 13   12     #   6EC5D6_h      #  9672000_h            #00015F???_h

8.1      0 12    6  6- #   6EC5D6_h      #   259C80_h  < 
8.2      6 12    9  3+ #   6EC5D6_h      #  12CE400_h  > 
8.3      6  9    7  2- #   6EC5D6_h      #   4B3900_h  < 
8.4      7  9    8  1+ #   6EC5D6_h      #   967200_h  > 

         7  8    7     #   238CD6_h      #   4B3900_h           #00015F08?_h

9.1      0  7    3  4- #   238CD6_h      #    4B390_h  < 
9.2      3  7    5  2+ #   238CD6_h      #   12CE40_h  < 
9.3      5  7    6  1+ #   238CD6_h      #   259C80_h  > 

         5  6          #   10BE96_h      #   12CE40_h           #00015F0A?_h

A.1      0  5    2  4- #   10BE96_h      #    12CE4_h  < 
A.2      2  5    3  1+ #   10BE96_h      #    4B390_h  < 
A.2      3  5    4  1+ #   10BE96_h      #    96720_h  < 

         4  5          #    75776_h      #    96720_h           #00015F0B?_h

B.1      0  4    2  2- #    75776_h      #    12CE4_h  < 
B.2      2  4    3  1+ #    75776_h      #    4B390_h  < 

         3  4          #    2A3E6_h      #    4B390_h           #00015F0B8_h

C.1      0  3    1  2- #    2A3E6_h      #    12CE4_h  < 
C.2      1  3    2  1+ #    2A3E6_h      #    259C8_h  < 

         2  3    2     #     4A1E_h      #    259C8_h  <        #00015F0BC_h

D.1      0  2    1     #     4A1E_h      #     9672_h  > 
D.2      0  1    0     #     4A1E_h      e.o.d. 

Conclusion :
-------------
#CE4D3A5D6_h = #9672_h * #15F0BC_h + #4A1E_h

Soit 55378683350 = 38514 x 1437884 + 18974


Le principe de le recherche du décalage binaire correct est répété jusqu’à obtenir un reste suffisamment petit. A chaque phase, la borne majorée stricte diminue et la borne minoré est remise à zéro pour le cas où le dividende serait un multiple (et qu’il "tomberait" rapidement à zéro).
On note qu’à chaque phase, on détermine le quotient des bits forts vers les bits faibles. Ce qui peut constituer un critère d’arrêt, si l’on ne cherche pas à déterminer le reste, mais que l’on cherche à calculer le quotient avec une certaine "incertitude".
Dernière édition par C.Ret le 13 juil. 2011 10:40, édité 1 fois.
SHARP PC-1211 + CE-121 + CE-122. | VIC 20 Commodore 128D + Printer P-803 + SD2iec. | TI-57 LCD | HP-28S + HP82240A | TI-74 BasiCalc | HP-41C + (2 memory + stat + IR) | HP-15C | HP Prime Color Touchscreen Graphing Calculator| TI-92 II | CASIO fx-602p + FA-1 | HP-71B 64K+JPC-ROM+HPIL+card reader . Sommaire des M.P.O..

Avatar de l’utilisateur
Pocket
Administrateur
Administrateur
Messages : 5813
Inscription : 24 mai 2002 16:55
Localisation : Toulouse
Contact :

Re: Division entière

Message par Pocket » 13 juil. 2011 09:58

Salut,
C.Ret a écrit :e.o.d.
Wow 8O

Merci pour cette brillante démonstration, on va sans doute essayer d'implémenter cette technique !
Pour la petite histoire, ça ne va pas être fait en logiciel, mais en VHDL dans un FPGA, et on ne dispose que de 100 cycles pour effectuer cette opération (en moyenne), car on doit tenir une cadence de 1 million de divisions par seconde : d'où mes questions subsidiaires pour les fortiches :
- quel est le nombre max d'étapes dans le pire cas ?
- quel est le nombre moyen d'étapes ?

A+
Pocket, voit tout, sait tout, lit l'avenir dans les entrailles d'une base phpBB ...
Image

Avatar de l’utilisateur
zpalm
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 2498
Inscription : 03 mai 2008 15:33
Localisation : Grenoble

Re: Division entière

Message par zpalm » 13 juil. 2011 10:11

Ça peut peut être te servir: a division 32 by 32 in 32 cycles in VHDL

Je n'ai pas vérifié si ça marche bien...

Avatar de l’utilisateur
Pocket
Administrateur
Administrateur
Messages : 5813
Inscription : 24 mai 2002 16:55
Localisation : Toulouse
Contact :

Re: Division entière

Message par Pocket » 13 juil. 2011 10:13

Salut,
zpalm a écrit :Ça peut peut être te servir: a division 32 by 32 in 32 cycles in VHDL

Je n'ai pas vérifié si ça marche bien...
Wow aussi 8O

Je vais soumettre ça a mon codeur fou, je vous dirais.

A+
Pocket, voit tout, sait tout, lit l'avenir dans les entrailles d'une base phpBB ...
Image

Avatar de l’utilisateur
zpalm
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 2498
Inscription : 03 mai 2008 15:33
Localisation : Grenoble

Re: Division entière

Message par zpalm » 13 juil. 2011 10:36

Oui, tiens nous au courant et si possible de partager le code, dis nous comment vous avez implémenté cette division 36 par 16 en VHDL. Il y quelques années je faisais moi aussi du VHDL, mais pas pour des FPGA, pour des ASICs...

J'avais beaucoup aimé cette période de ma vie professionnelle ou on créait des circuits intégrés à partir d'un langage de haut niveau avec toutes les étapes, specs, proto en VHDL, programmation de chaque module, définition du test bench et validation de chaque module, intégration et validation toujours sous VHDL, puis synthèse (là c'est un peu magique de passage du VHDL aux transistors ...) et validation des timings et des chemins critiques, puis optimisation et itérations, ensuite JTAG et vecteurs de test de production et enfin l'envoi en prod chez le fondeur puis deuxième moment magique: la réception des circuits, la fabrication des cartes et oh miracle le premier boot qui fonctionne! De grands moments ....

Avatar de l’utilisateur
Demoniak
Fonctionne à 300 bauds
Fonctionne à 300 bauds
Messages : 80
Inscription : 03 oct. 2004 15:47
Localisation : Dunkerque (59)
Contact :

Re: Division entière

Message par Demoniak » 13 juil. 2011 11:16

Un petit truc en passant, pour implémenter une division ultra-rapide en Z80, j'avais utilisé la méthode des logarithmes.

En effet, A / B = Exp( Log( A ) - Log( B ) )
Il suffit de se créer une table de Exp et une table de Log, ensuite ça n'est qu'une question de 3 indexations dans les tables.

Avatar de l’utilisateur
Pocket
Administrateur
Administrateur
Messages : 5813
Inscription : 24 mai 2002 16:55
Localisation : Toulouse
Contact :

Re: Division entière

Message par Pocket » 13 juil. 2011 12:03

Salut,
Demoniak a écrit :Un petit truc en passant, pour implémenter une division ultra-rapide en Z80, j'avais utilisé la méthode des logarithmes.

En effet, A / B = Exp( Log( A ) - Log( B ) )
Il suffit de se créer une table de Exp et une table de Log, ensuite ça n'est qu'une question de 3 indexations dans les tables.
Oui, mais A étant sur 36 bits, je me vois mal créer une table 64 milliards d'entrées ;)

A+
Pocket, voit tout, sait tout, lit l'avenir dans les entrailles d'une base phpBB ...
Image

Avatar de l’utilisateur
fabu
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1338
Inscription : 16 oct. 2003 22:54
Localisation : Aveyron

Re: Division entière

Message par fabu » 13 juil. 2011 13:21

Pocket a écrit :
Je vais soumettre ça a mon codeur fou, je vous dirais.

A+
Mais qu'est ce que vous nous préparez encore !! :lol:
Je recherche du soft C64,Amstrad,Amiga,Msx

Avatar de l’utilisateur
Pocket
Administrateur
Administrateur
Messages : 5813
Inscription : 24 mai 2002 16:55
Localisation : Toulouse
Contact :

Re: Division entière

Message par Pocket » 13 juil. 2011 14:05

Salut,
fabu a écrit :Mais qu'est ce que vous nous préparez encore !! :lol:
C'est dans le cadre professionnel : on doit faire de l'acquisition de tensions à haute précision dans une très large gamme, le tout à 1MHz avec des protections sur seuils programmables qui déclenchent en moins de 10µs ...

A+
Pocket, voit tout, sait tout, lit l'avenir dans les entrailles d'une base phpBB ...
Image

Avatar de l’utilisateur
Ngtb
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 426
Inscription : 15 avr. 2009 14:54
Localisation : 43.527712172308306 , 1.4864212274551392

Re: Division entière

Message par Ngtb » 13 juil. 2011 16:21

Ca me rappelle les chinoiseries capillo-tractées auxquelles devait se livrer un copin quand il bossait chez Leroy sur des systèmes de freinage
Les génies composent, les pros exécutent.

Répondre

Revenir vers « Tous les Pockets »