Bric-à-Brac de Lord Nelson

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Bric-à-Brac de Lord Nelson

Message par Ollivier »

Il n'y a aucun problème avec le rythme: le but est d'aboutir à ses fins. Je préfère que tu restes au stade où j'en suis: gérer un seul chiffre, mais bien. Plutôt que des millions de chiffres sans être sûr que ça fonctionne.

Quand tu fais l'inventaire des variables nécessaires pour l'addition de 2 chiffres, tu as un chiffre en résultat et un chiffre en retenue de résultat.

Résultat:

une addition c'est en fait (et toujours):

3 entrées:
EntreeA
EntreeB
EntreeRetenue

2 sorties:
SortieX
SortieRetenue

Code : Tout sélectionner

Structure Valeur
EntreeA.S
EntreeB.S
EntreeRetenue.S

SortieX.S
SortieRetenue.S
EndStructure

Procedure Ajout(*Valeur.Valeur)

With *Valeur
 \SortieX = Right(Str(Val(\EntreeA) + Val(\EntreeB) + Val(\EntreeRetenue)), 1)
 \SortieRetenue = Left(Str(Val(\EntreeA) + Val(\EntreeB) + Val(\EntreeRetenue) ), 1)
EndWith

EndProcedure

Define Valeur.Valeur
Je comprends que ça te plaise "plusse" de voir des millions de chiffres, mais déjà un seul chiffre mérite de s'y attarder.

Règle n2: une fois que l'on est certain à 100% que sa procédure/macro/fonction/méthode/zébulon fonctionne parfaitement, on fait l'inventaire des sous-fonctions qui la constituent.

C'est-à-dire que l'on écrit, noir sur blanc, la liste des différentes instructions utilisées.

Alors, Nelson, question: ma fonction "maquette" d'addition à un chiffre, elle fonctionne parfaitement à 100%?

Si oui, n'hésite pas à faire la liste des instructions utilisées entre with et endwith et à poster cette liste...
Lord Nelson
Messages : 355
Inscription : dim. 01/déc./2013 15:29

Re: Bric-à-Brac de Lord Nelson

Message par Lord Nelson »

Voici mon second jet, différent, repris totalement de zéro.
Je le préfère :)

Code : Tout sélectionner

; Addition maison
; Débuté le 12/11/2014

Procedure.S Ajoute(Nombre$, Addition$)
  
  Protected LectureNombre$, LectureAddition$, ChiffreNombre$, ChiffreAddition$, ChiffreUniter$, ResultatFinale$
  Protected Index, Resultat, Retenu, Position
  Protected TailleGenarale.Q, NombreOctetEcrit.Q
  Protected *MemoireIDNombre, *MemoireIDAddition, *MemoireIDResultatAddition
  
  ; Ont détermine quel nombre est le plus grand.
  If Len(Nombre$) > Len(Addition$) ; Si longueur de Nombre$ est plus grand que Addition$.
    Addition$ = RSet(Addition$, Len(Nombre$), "0") ; Ont formate la chaîne Addition pour la remplire de 0 au début pour quel soit de même taille que Nombre$.
    
  ElseIf Len(Nombre$) < Len(Addition$) ; Sinon Si longueur de Nombre$ est plus petit que Addition$.
    Nombre$ = RSet(Nombre$, Len(Addition$), "0") ; Ont formate la chaîne Nombre$ pour la remplire de 0 au début pour quel soit de même taille que Addition$.
    
  EndIf
  
  TailleGenarale.Q = Len(Nombre$) ; Taille de nombre$, de toute façon les deux chaîne sont de même longueur.
  
  ; *MemoireIDNombre = Position de début du nombre dans la mémoire.
  *MemoireIDNombre = AllocateMemory(TailleGenarale.Q) ; Alloue une zone mémoire contigüe de la 'TailleGenarale.Q' spécifiée (en octets).
  
  ; Si *MemoireIDNombre est différente de 0
  If *MemoireIDNombre
    
    ;Debug "Adresse de début de la zone mémoire de Nombre$ = " + Str(*MemoireIDNombre) + ", Taille du bloc mémoire = " + Str(TailleGenarale.Q)  + " octets."
    
    ; Stocke le Nombre$ dans la zone mémoire et retourne le nombre d'octets écrit.
    NombreOctetEcrit.Q = PokeS(*MemoireIDNombre, Nombre$, TailleGenarale.Q, #PB_Ascii)
    
    If NombreOctetEcrit.Q > 0 ; Si le nombre d'octet écrit est supérieur à 0
      
      ;Debug "Nombre d'octets écrit = " + Str(NombreOctetEcrit.Q)
      
      ; Lecture du nombre à l'adresse de *MemoireIDNombre
      LectureNombre$ = PeekS(*MemoireIDNombre, TailleGenarale.Q, #PB_Ascii)
      ;Debug "La zone mémoire " + Str(*MemoireIDNombre) + ", contient: " + LectureNombre$
      
    Else
      Debug "Impossible d'écrire le Nombre$ dans la mémoire !"
      
    EndIf
    
  Else
    Debug "Impossible d'allouer la mémoire demandée !"
    
  EndIf 
  
  ;Debug ""
  
  ; *MemoireIDAddition = Position de début du nombre dans la mémoire.
  *MemoireIDAddition = AllocateMemory(TailleGenarale.Q) ; Alloue une zone mémoire contigüe de la 'TailleGenarale.Q' spécifiée (en octets).
  
  ; Si *MemoireIDAddition est différente de 0
  If *MemoireIDAddition
    
    ;Debug "Adresse de début de la zone mémoire de Addition$ = " + Str(*MemoireIDAddition) + ", Taille du bloc mémoire = " + Str(TailleGenarale.Q)  + " octets."
    
    ; Stocke le Addition$ dans la zone mémoire et retourne le nombre d'octets écrit.
    NombreOctetEcrit.Q = PokeS(*MemoireIDAddition, Addition$, TailleGenarale.Q, #PB_Ascii)
    
    If NombreOctetEcrit.Q > 0 ; Si le nombre d'octet écrit est supérieur à 0.
      
      ;Debug "Nombre d'octets écrit = " + Str(NombreOctetEcrit.Q)
      
      ; Lecture du nombre à l'adresse de *MemoireIDAddition.
      LectureAddition$ = PeekS(*MemoireIDAddition, TailleGenarale.Q, #PB_Ascii)
      ;Debug "La zone mémoire " + Str(*MemoireIDAddition) + ", contient: " + LectureAddition$
      
    Else
      Debug "Impossible d'écrire le Addition$ dans la mémoire !"
      
    EndIf
    
  Else
    Debug "Impossible d'allouer la mémoire demandée !"
    
  EndIf 
  
  ;Debug ""
  
  ; Passont à l'addition des nombres:
  
  ; Création de la mémoire pour le résultat de l'addition.
  *MemoireIDResultatAddition = AllocateMemory(TailleGenarale.Q + 1) ; + 1 pour l'éventuel retenu de fin
  
  If *MemoireIDResultatAddition
    
    ; Parcourt de la zone mémoire Nombre$ et Addition$ depuis la fin vers le début.
    For Index = TailleGenarale.Q - 1 To 0 Step - 1
      
      ; Extraction du chiffre Nombre$ depuis la fin vers le début.
      ChiffreNombre$ = PeekS(*MemoireIDNombre + Index, 1, #PB_Ascii)
      
      ;Debug "ChiffreNombre$ n° " + Str(Index) + " = " + ChiffreNombre$
      
      ; Extraction du chiffre Addition$ depuis la fin vers le début.
      ChiffreAddition$ = PeekS(*MemoireIDAddition + Index, 1, #PB_Ascii)
      
      ;Debug "ChiffreAddition$ n° " + Str(Index) + " = " + ChiffreAddition$
      
      ; Ont calcule combien fait ChiffreNombre$ + ChiffreAddition$, ont ajoute la retenu aussi.
      Resultat = (Val(ChiffreNombre$) + Val(ChiffreAddition$)) + Retenu
      
      ;Debug ""
      
      ;Debug ChiffreNombre$ + " + " + ChiffreAddition$ + " + " + Str(Retenu) + " = " + Str(Resultat)
      
      If Resultat > 9
        ; Ont extrait la valeur des unités du résultat.
        ChiffreUniter$ = Mid(Str(Resultat), 2, 1)
      Else
        ChiffreUniter$ = Mid(Str(Resultat), 1, 1)
      EndIf
      
      ;Debug "Unité = " + ChiffreUniter$
      
      If Resultat > 9
        ; Ont extrait la valeur des dizaine du résultat.
        ChiffreDizaine$ = Mid(Str(Resultat), 1, 1)
      Else
        ChiffreDizaine$ = "0"
      EndIf
      
      ;Debug "Dizaine = " + ChiffreDizaine$
      
      If Resultat > 9
        ; Retenu devient égale à la dizaine (Sera toujours soit 0, soit 1).
        Retenu = Val(ChiffreDizaine$)
      Else
        Retenu = 0
      EndIf
      
      ;Debug "Retenue = " + Str(Retenu)
      
      ;Debug "---------------------------------------------------------------------------"
      
      ; Ont enregistre l'unité.
      PokeS(*MemoireIDResultatAddition + Position, ChiffreUniter$, 1, #PB_Ascii)
      Position + 1
      
    Next
    
    If Retenu > 0
      PokeS(*MemoireIDResultatAddition + Position, Str(Retenu), 1, #PB_Ascii)
    EndIf
    
    ;Debug ""
    
  Else
    Debug "Impossible d'allouer la mémoire demandée !"
    
  EndIf 
  
  ResultatFinale$ = PeekS(*MemoireIDResultatAddition, -1, #PB_Ascii)
  
  FreeMemory(*MemoireIDNombre)  ; sera également effectué automatiquement à la fin du programme.
  FreeMemory(*MemoireIDAddition); sera également effectué automatiquement à la fin du programme.
  FreeMemory(*MemoireIDResultatAddition); sera également effectué automatiquement à la fin du programme.
  
  ProcedureReturn ReverseString(ResultatFinale$)
EndProcedure

Nombre1$ = "123"
Nombre2$ = "456"
Resultat$ = ""

For I = 1 To 1000
  Resultat$ = Ajoute(Nombre1$, Nombre2$)
  Debug Nombre1$ + " + " + Nombre2$ + " = " + Resultat$
  Nombre1$ = Resultat$
Next
Avec un test sur deux nombre faisant chacun 96 796 974 chiffres
j'obtiens un temps de 74, 596 Secondes.
Dernière modification par Lord Nelson le sam. 15/nov./2014 17:53, modifié 2 fois.
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Bric-à-Brac de Lord Nelson

Message par Ollivier »

Je comprends que tu fasses un jet... Mais tu loopes quelque chose. J'en reste à attendre la liste des instructions. S'il n'y en a pas, ce n'est pas grave...
Lord Nelson
Messages : 355
Inscription : dim. 01/déc./2013 15:29

Re: Bric-à-Brac de Lord Nelson

Message par Lord Nelson »

Dis ho, je me casse la tête pour te faire plaisir ok hein :wink:
C'est pas toi qui m'as demandé de faire une Addition maison avec des chaîne de caractères ?

J'ai accepté pour te faire plaisir parce que tu me l'avais demandé et parce que aussi je voulais faire se défis là :)
J'aurais très bien pue te laisser raconter se que tu veux !

Je me casse la tête sur ce code et je t'en donne le fruit, pour toi c'est peut
être nul ou ça ne vaux rien mais sache que pas pour moi :wink:

Sache que j'avais jamais fait ça avent, que j'ai fais ça sans aucune aide et que j'ai
fais ça le plus proprement possible et le plus optimisé possible :wink:

J'aimerais avoir de la reconnaissance un minimum tu comprends ? :)
En tous les cas, j'ai trouvé ce défis intéressant et j'en est pas plus bavé que ça, un peut mais ça va.

Par contre la ou j'ai peur c'est pour faire la même chose avec la Multiplication, la Soustraction, Division...
Voila :)
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Bric-à-Brac de Lord Nelson

Message par Ollivier »

Je te prie d'agréer l'expression intégrale de ma considération la plus établie.
Lord Nelson
Messages : 355
Inscription : dim. 01/déc./2013 15:29

Re: Bric-à-Brac de Lord Nelson

Message par Lord Nelson »

Ollivier a écrit :Je te prie d'agréer l'expression intégrale de ma considération la plus établie.
J'en demandais pas t'en lol :lol:
Juste me dire se que tu en pense, pour quelqu'un qui n'as jamais fait ça c'est pas si mal non ?
De plus le gestion mémoire, c'est pas simple quand tu connais pas.

Ya moyen de faire mieux et justement, j'aimerais apprendre à faire mieux.
Ya t-il plus rapide ?

Tu as vue que j'ai fais le plus rapide possible, je trouve que c'est assez rapide quand même non ?
Pour ton code plus haut, j’avoue ne pas avoir trop compris.
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Bric-à-Brac de Lord Nelson

Message par Ollivier »

Au lieu d'insérer plusieurs arguments en tête de procédure qui ne seront que des entrées de valeurs dans ta procédure, il est plus judicieux de ne rentrer qu'un argument qui est un pointeur (adresse mémoire) vers une zone mémoire (variable dite structurée) préalablement allouée (ici par Define) et qui permet d'avoir autant d'entrées et de sorties que l'on veut vers et depuis une procédure.

Bus : nom de la structure
Mem1 : 1er entier de la structure
Mem2 : 2nd entier de la structure
Mem3 : 3ème entier de la structure
Centre : nom de la procédure
*X : pointeur dans la procédure(ici pointe les 3 champs de "bus")
X : variable structurée

Code : Tout sélectionner

Structure Bus
   Mem1.I
   Mem2.I
   Mem3.I
EndStructure




Procedure Centre(*X.Bus)
*X\Mem3 = *X\Mem1 + *X\Mem2
EndProcedure

Define X.Bus
X\Mem1 = 10
X\Mem2 = 20
Centre(X)
Debug X\Mem3

Lord Nelson
Messages : 355
Inscription : dim. 01/déc./2013 15:29

Re: Bric-à-Brac de Lord Nelson

Message par Lord Nelson »

Je ne suis pas familier avec se genre de chose, j'y comprends pratiquement rien à ça moi.
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Bric-à-Brac de Lord Nelson

Message par Ollivier »

Tu vois une procédure à vide comme ça:

Code : Tout sélectionner

Procedure AVide()
EndProcedure
C'est bien, car quand on veut retourner une seule valeur, ça marche. On fait ceci:

Code : Tout sélectionner

Procedure Test()
ProcedureReturn 99
EndProcedure

Debug Test() ; Affiche 99
Mais si l'on veut retourner 2 valeurs, c'est cuit.
Il y a plusieurs techniques. L'une d'entre elles consiste à imaginer une procédure à vide comme ça:

Code : Tout sélectionner

Structure Rien
EndStructure

Procedure Vide(*Ceci.Rien)
EndProcedure
Dans ce cas là, la procédure à vide qui ne fait visiblement pas grand chose, communique via le pointeur *Ceci. Là, ceci n'a rien, mais c'est normal, puisque la structure est vide (et Juste, c'est son nom).

Renommons cette structure et cette procédure pour la bonne cause. On va faire en sorte que la procédure nous rende 2 données: "Raoul" et "Robert", sous forme de chaîne.

Code : Tout sélectionner

Structure Memoire
LePremier.S
LeDeuxieme.S
EndStructure

Procedure Renseigner(*Ceci.Memoire)
*Ceci\LePremier = "Raoul"
*Ceci\LeDeuxieme = "Robert"
EndProcedure


Define Carnet.Memoire
Renseigner(Carnet)
Debug Carnet\LePremier
Debug Carnet\LeDeuxieme
La procédure Renseigner() a retourné deux valeurs.
Tu peux donner et retourner autant de valeurs que tu veux: il suffit de les définir au préalable dans une structure.
Lord Nelson
Messages : 355
Inscription : dim. 01/déc./2013 15:29

Re: Bric-à-Brac de Lord Nelson

Message par Lord Nelson »

Merci Ollivier :)
Mais je vais pour le moment arrêter là, j'ai pas les capacitées pour faire une librairie de calcule de nombre.

Actuellement je suis sur un autre système binaire:
0 = 0
1 = 1
10 = 2
11 = 3
100 = 4
110 = 5
111 = 6
1000 = 7
1100 = 8
1110 = 9
1111 = 10
10000 = 11
11000 = 12
11100 = 13
11110 = 14
11111 = 15
100000 = 16
110000 = 17
111000 = 18
111100 = 19
111110 = 20
111111 = 21
1000000 = 22
1100000 = 23
1110000 = 24
1111000 = 25
1111100 = 26
1111110 = 27
1111111 = 28
10000000 = 29
11000000 = 30
11100000 = 31
11110000 = 32
11111000 = 33
11111100 = 34
11111110 = 35
11111111 = 36
100000000 = 37
110000000 = 38
111000000 = 39
111100000 = 40
111110000 = 41
111111000 = 42
111111100 = 43
111111110 = 44
111111111 = 45
1000000000 = 46
1100000000 = 47
1110000000 = 48
1111000000 = 49
1111100000 = 50
1111110000 = 51
1111111000 = 52
1111111100 = 53
1111111110 = 54
1111111111 = 55
Je me demande comment faire ceci et que se soit réversible dans les deux sens, je cherche :)
Si quelqu’un à une idée sur comment faire ceci :)

Edit: Je ne parviens pas à trouver la formule, comme ça ne fonctionne pas comme du binaire, je trouve pas :(
Quelqu'un pourrais me mettre sur une piste svp ?
Dernière modification par Lord Nelson le mer. 19/nov./2014 20:31, modifié 1 fois.
Avatar de l’utilisateur
SPH
Messages : 4937
Inscription : mer. 09/nov./2005 9:53

Re: Bric-à-Brac de Lord Nelson

Message par SPH »

Dis moi, a quoi cela va t'il te servir ?

!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.12LTS- 64 bits
Lord Nelson
Messages : 355
Inscription : dim. 01/déc./2013 15:29

Re: Bric-à-Brac de Lord Nelson

Message par Lord Nelson »

A faire mes expériences comme d'habitude :)
Avatar de l’utilisateur
SPH
Messages : 4937
Inscription : mer. 09/nov./2005 9:53

Re: Bric-à-Brac de Lord Nelson

Message par SPH »

Si tu avais un but precis a exposer, peut etre qu'on pourrait + t'aider ! 8)

!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.12LTS- 64 bits
Lord Nelson
Messages : 355
Inscription : dim. 01/déc./2013 15:29

Re: Bric-à-Brac de Lord Nelson

Message par Lord Nelson »

Je suis sur se nouveau casse tête depuis un moment déjà et j'arrive pas à trouver la logique pour reproduire la chose !
Ici, ont peut pas diviser le nombre par 2 et prendre le reste, ça ne fonctionne apparemment pas :(
J'ai besoin de ça pour un nouvel essaie d'une méthode pour la compression d'image / données.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Bric-à-Brac de Lord Nelson

Message par djes »

Lord Nelson a écrit :Merci Ollivier :)
Mais je vais pour le moment arrêter là, j'ai pas les capacitées pour faire une librairie de calcule de nombre.

Actuellement je suis sur un autre système binaire:
0 = 0
1 = 1
10 = 2
11 = 3
100 = 4
110 = 5
111 = 6
1000 = 7
1100 = 8
1110 = 9
1111 = 10
10000 = 11
11000 = 12
11100 = 13
11110 = 14
11111 = 15
100000 = 16
110000 = 17
111000 = 18
111100 = 19
111110 = 20
111111 = 21
1000000 = 22
1100000 = 23
1110000 = 24
1111000 = 25
1111100 = 26
1111110 = 27
1111111 = 28
10000000 = 29
11000000 = 30
11100000 = 31
11110000 = 32
11111000 = 33
11111100 = 34
11111110 = 35
11111111 = 36
100000000 = 37
110000000 = 38
111000000 = 39
111100000 = 40
111110000 = 41
111111000 = 42
111111100 = 43
111111110 = 44
111111111 = 45
1000000000 = 46
1100000000 = 47
1110000000 = 48
1111000000 = 49
1111100000 = 50
1111110000 = 51
1111111000 = 52
1111111100 = 53
1111111110 = 54
1111111111 = 55
Je me demande comment faire ceci et que se soit réversible dans les deux sens, je cherche :)
Si quelqu’un à une idée sur comment faire ceci :)

Edit: Je ne parviens pas à trouver la formule, comme ça ne fonctionne pas comme du binaire, je trouve pas :(
Quelqu'un pourrais me mettre sur une piste svp ?
C'est bien de chercher, mais là tu vois bien que ça prend plus de place que du binaire "habituel", l'intérêt semble inexistant. Tu as étudié les algos de Lempel, Ziv, Huffman et autres comme on t'avait dit ? Franchement tu verras, c'est très intéressant. Et est-ce que tu connais le BCD ? Encore un petit truc, avec PB, tu peux très facilement faire de l'assembleur, c'est idéal pour manipuler les données à un très bas niveau comme tu le souhaites.
Répondre