Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1285 connectés 

 


Dernière réponse
Sujet : Passer d'une chaine de chiffre à une chaine de bit???
HelloWorld j'apporte une petite pierre a l'edifice ...
si tu as l'intension de manipuler ces nombres (addition, multiplication, ...) il serait petetre bon de lire cet article
koikilensoit, c'est tout de meme une bonne doc informative :
http://www.citeweb.net/discase/9/GDNOMBRE.htm  
 
les exemples donnés manipulent des tableaux de chiffres ...
c'est donc tres proche de ton cas (au lieu de stocker ton nombre de caractere, tu le stocke dans un tableau de chiffres)

Votre réponse
Nom d'utilisateur    Pour poster, vous devez être inscrit sur ce forum .... si ce n'est pas le cas, cliquez ici !
Le ton de votre message                        
                       
Votre réponse


[b][i][u][strike][spoiler][fixed][cpp][url][email][img][*]   
 
   [quote]
 

Options

 
Vous avez perdu votre mot de passe ?


Vue Rapide de la discussion
HelloWorld j'apporte une petite pierre a l'edifice ...
si tu as l'intension de manipuler ces nombres (addition, multiplication, ...) il serait petetre bon de lire cet article
koikilensoit, c'est tout de meme une bonne doc informative :
http://www.citeweb.net/discase/9/GDNOMBRE.htm  
 
les exemples donnés manipulent des tableaux de chiffres ...
c'est donc tres proche de ton cas (au lieu de stocker ton nombre de caractere, tu le stocke dans un tableau de chiffres)
TotOOntHeMooN Pour le soft, essai avec PowerPoint...
TotOOntHeMooN OK, bon scan, bon weekend et a lundi.  
Avec une solution...
Carbon_14 Voui. Plein de chimie et de l'info le soir/WE/partie des vacances (l'info est un outil utilitaire pour moi). Mes collègues sont restés à QB4.5, voire Mathematica/Mapple/ et je sais pas quoi.
 
Quand on est pas pro, c'est fou ce qu'on perd de temps à réinventer la Win_roue, surtout en C. Le Pingouin_roue, ça promet aussi...
 
Faut que je finisse scannages de diapos d'un mariage d'un collègue le week-end dernier, fabrication du CD, trouver/écrire soft(?) pour faire diaporama, .. donc pas de temps pour le sujet.
 :(  
 
 :) Super algo ultra rapide multibase lundi matin sur des chaînes de longueur quelconque :??: ...
TotOOntHeMooN Oui, mais se sera pour ce weekend, car j'ai pas envie de partir trop tard du travail, pour une fois...
D'ailleur, tu fais quoi comme job CARBON_14 ? Dans la recherche scientifique je supose ?
Carbon_14 Un problème en VB(3) est la lenteur d'accès des fonctions de maipulation de chaînes. En VBA, c'est peut-être mieux.
 
Le traitement d'une chaîne de 1024 caractères issue d'un oscillo (de grande marque :)) demandait 1 seconde pour transformer les 1024 char en 1024 int via la fonction mid$() (PC à 33MHz).
J'avais écrit une DLL en (B)C pour utiliser avec VB(3), ca prenait 1,1 milli seconde  :D!! En C, un char <=> int direct => très rapide.
 
On va y arriver !  :hello:
TotOOntHeMooN Tu fais confiance à la calculatrice windows CARBON_14 ? :crazy:  
Bon, ça se tente, non ?
TotOOntHeMooN Merci pour ta solution nur.
Je jette un oeuil sur l'algo que tu utilises...  
A première vue, ça doit pas être bien rapide, mais je me trompe peut-être.
Tu ne peux pas nous pondre la même chose en C/C++ ?
Carbon_14 TotOOntHeMooN  
La calculatrice Windows donne 0100 1101 0010 Bin pour 1234 Décimal ou 4D2 Hexa.
C'est donc tout bon.   :jap:
nur Une version sur Excel sans limitation de bits:
 
 
 
 
 
Dim bi(126) 'ou plus
 
 
Sub rr()
chainechiffre = "1234567890123456789012345678901234567"
lg = Len(chainechiffre) - 1
cc = Len(chainechiffre) - 1
 
i = O
While cc > 0
i = i + 1
compty = compty + Mid(chainechiffre, i, 1) * 10 ^ cc
cc = cc - 1
Wend
compty = compty + Mid(chainechiffre, lg + 1, 1)
dd = 4 * lg - 2
 
While (chainechiffre / 2 ^ dd) < 1
dd = dd - 1
Wend
i = dd
cpt = 1
reste = chainechiffre - 2 ^ (i)
bi(cpt) = i
i = i - 1
 
Do
  Do
    divis = reste / 2 ^ i
    If (divis < 1) Then i = i - 1
  Loop While divis < 1
cpt = cpt + 1
bi(cpt) = i
reste = reste - 2 ^ i
i = i - 1
 
Loop While reste > 1
 
If Mid(chainechiffre, lg + 1, 1) Mod 2 > 0 Then
cpt = cpt + 1
bi(cpt) = 0
End If
 
 
For i = 1 To cpt
Sheets("feuil1" ).Range("a1" ).Offset(i - 1).Value = bi(i)
Next
 
 
retrans (cpt)
End Sub
 
 
 
 
Sub retrans(ch)
'ch=cpt
chainet = ""
For i = 1 To ch
If bi(i) >= 0 Then chainet = chainet & "1"
diff = bi(i) - bi(i + 1) - 1
If diff > O Then
  For j = 1 To diff
    chainet = chainet & "0"
  Next
End If
Next
MsgBox (chainet)
Sheets("feuil1" ).Range("C41" ).Value = chainet & "B"
End Sub
TotOOntHeMooN Ca marche sur papier, alors il n'y a pas de raison...
Par example, pour diviser 1234 par 2, tu vas essayer 1(0x), puis 12(6x), puis 3(1x), puis 14(7x) il te reste 0 et ton resultat est 617, et tu recommence.
si tu divises 1234 toujours par 2, mais en prenant des tranches de 2, tu vas essayer 12(6x), puis 34(17x), il te reste 0, et ton resultat est 617, mais tu n'a fait que deux divisions au lieu de 4 !
Maintenant, tu peux augmenter la taille des tranche (8max, pour un entier). Ainsi, 1234 poura donner le resultat 617 reste 0 en une seule fois, et ceux pour tous nombre contennu dans une tranche.
Biensur, le resultat est toujours binaire ;) dans notre cas.
Si maintenant, on fait les division par 16, avec des tranches de 8, on aura le calcul suivant:
1234/16 (77x ou plutot 4Dx) reste 2
et onfait la "conversion" hexa -> binaire, comme je l'ai expliqué il y a quelques jours.
4: 0100
D: 1101
2: 0010
donc 1234 = 0100 1101 0010
Carbon_14 Ca serait quand même intéressant (j'utilise ma montre sur mon 486/100 en faisant des boucles répétitives ( :( )) de vérifier si on va 64 fois plus vite en coupant en tranches et en divisant par 16..
 
Je me demandais juste si on peut diviser par 16 une chaîne découpée en tronçons. Ne faut-il pas diviser la chaine d'un seul bloc et reposer l'opération comme on l'a fait (dans une autre base) selon TotOOntHeMooN  Posté le 03-08-2001 à 09:12:07.
 
Casse-tête du vendredi.  :D . Restons binaires..
TotOOntHeMooN Si quelqu'un à un Linux sous la main, il execute la commande time suivi du nom de son programme comme argument.
Pas besoin de se prendre la tête a écrire une routine !
Carbon_14 Comme quoi, quand tout le monde a des idées, on peut arriver à "booster" les algorithmes.  
 
On part de la base, et les suggestions aident à pulvériser le temps de calcul.
 
Un courageux pour lancer des tests et mesurer le gain ?  :??:
TotOOntHeMooN En se moment, on se pose plus des questions d'optimisation de de calcul ;)  
Mais c'est vrai, que diviser par 16 et convertir chaque octet en sa valeur binaire, et bien plus efficace.
 
Depuis le debut, toules les methodes proposées repose sur le meme principe, qui est de prendre caractere par caractere dans la chaine de depart, et effectuer les divisions.
 
On peut très bien prendre par tranche de 8 caracteres, convertir le bout de chaine en entier, et effectuer la division. (encore 8 fois plus vite.
 
Si on cumule les deux methodes, on va 64x plus vite !
Carbon_14 :D A tester sur des nombres de 35 chiffres.
 
L'utilisateur va pouvoir choisir (il a toutes les données pour tester lui-même).
 
Dans mon exemple de l'autre jour, on peut aussi laisser tomber les zéros de poids fort au fur et à mesure qu'on fait les divisions. Ca économise pas mal de temps  :lol: .
Mara's dad Une idée pour aller plus vite.
 
Au lieu de faire les divisions par 2, pour obtenir le nombre en binaire, ne serait-il pas plus rapide de faire une conversion en hexa ( divisions par 16 ) donc 8 fois moins de divisions.
 
Ensuite, la conversion de hexa vers binaire est triviale.
Carbon_14 Cela n'empêche qu'il faut des fois NE PAS OUBLIER d'ajouter 0,5 quand on fait des divisions car en float, on a des fois des surprises (127,99999 / 128,0000 ne donne pas 1).
 
 :D
TotOOntHeMooN Bon, la prochaine fois je réfléchirais avant de dire une connerie... Il faut bien mettre 1, pour etre sur du resultat.
TotOOntHeMooN Dans la série je discute tout seul, je voudrait apporter une petite modification sur la formule donnée par tfj57.
 
a la fin, il ne faut pas ajouter 1, mais 0.5
En effet, si la division entre les deux reel, donne un resultat "juste", genre 128.00000000 (ca arrive souvant) et que l'on ajoute 1, alors la taille de la chaine allouée après conversion en nombre entier (tronquage) sera de 129 et non pas 128.
Le fait d'ajouter 0.5, permet d'avoir un résultat à l'unitée supérieure, seulement si nécessaire.
TotOOntHeMooN Si ça intéresse quelqu'un, j'ai fait une variante, qui permet de convertir des grands nombres entiers entre n'importe quelle base.
(200 max)
TotOOntHeMooN Bon, comme j'ai vu qu'une autre personne avait posté une réponce, j'ai pris un p'tit moment sur mon travail, pour finir ma version.
Je me suis permis de prendre la formule que tjf57 a mis en commentaire, car la "mienne" (fait maison) devenait trop aproximative, quand la chaine donnée grandissait.  
Cette version n'a pas de limite en taille.
 
-------------------------------------------------------------
 
#include <stdio.h>
#include <string.h>
#include <math.h>
 
// macros de conversion ASCII <-> chiffre
#define ATOC(a) ((a)-0x30)
#define CTOA(c) ((c)+0x30)
 
// retourne une chaine binaine, valeur de la  
// chaine decimale passee en paramettre
const char * dec2bin(const char *dec)  
{  
 char *binString, *decString;  
 int binSize, decSize;
 int binPos, decPos;  
 int valeur, reste;
 
 // initialisation
 decSize = strlen(dec);
 binSize = (int)(log(pow(10, decSize))/log(2) + 1);
 
 // allocation memoire
 decString = new char[decSize+1];  
 binString = new char[binSize+1];  
 
 // copie de la chaine a traiter
 strcpy(decString, dec);
 
 for (binPos=binSize-1 ; binPos>=0 ; binPos--)  
 {
   reste = 0;  
   for (decPos=0 ; decPos<decSize ; decPos++)  
   {  
     valeur = ATOC(decString[decPos]) + reste*10;
     reste = valeur % 2;
     decString[decPos] = CTOA(valeur>>1);  
   }  
   // ecriture de la chaine binaire
   binString[binPos] = CTOA(reste);
 }
 // fin de la chaine binaire
 binString[binSize] = '\0';
 
 // libere la memoire prise par decString
 delete []decString;
 
 // retourne l'adresse de la chaine binaire
 return (binString);
}  
 
 
// Essai  
int main()
{  
 const char dec[] = "12345678901234567890123456789012345";
 const char *bin  = dec2bin(dec);
 
 printf ("%s\n", bin);
 
 // si plus besoin de bin, il faut liberer la memoire
 delete [](void*)bin;
 
 return 0;
}  
 
-------------------------------------------------------
 
Mon idée de départ était de faire les divisions sur 8 chiffres à la fois, mais cette version de base va déjà très bien.  
Et tout le monde a déjà posté la sienne, alors ...
tfj57 Hier j'avais fait ce qui est ci-dessous, mais CARBON_14 m'a bien devancé.
 
Je poste quand même ce petit programme pour donner une autre solution qui dans la base est la même que celle de CARBON_14.
 
En commentaire il y a la formule qui donne le nombre de chiffres de la chaine résultante.
 
Il peut très facilement être adaptée pour généraliser la conversion d'une base de départ vers une base d'arrivée.
 
Attention, les tableaux ont le chiffre le moins significatif en 0, l'initialisation du style tab[10]="1234" ne fait pas cela, mais le contraire !!!
 
A+
----------------------------------
#define NBDEC  36   /* nombre de chiffres à convertir */
#define NBBIN  120  /* nombre de chiffres du résultat = INT( LOG(10^NBDEC)/LOG(2) ) + 1 */
 
main()
{
   char TableDec[NBDEC+1];
   char TableBin[NBBIN+1];
   int i,j,reste,temp;
 
   /* Initialisation de TableDec en ASCII avec le chiffre le moins significatif en 0 */
   /* Après la conversion, le contenu de ce tableau sera perdu */
 
   /* transformation ASCII en décimal */
   for (i=0;i<NBDEC;i++)
      TableDec[i]-='0';
 
   /* chiffre binaire du moins significatif au plus significatif */
   for (j=0;j<NBBIN;j++)
   {
      reste=0;
 
      /* on fait la division par 2 du grand nombre décimal avec retenue */
      /* chiffre décimal du plus significatif au moins significatif */
      for (i=NBDEC-1;i>=0;i--)
      {
         temp=reste * 10 + TableDec[i]; /* 10 pour la base de départ */
         TableDec[i]=temp / 2;          /* 2 sur les 2 lignes */
         reste=temp % 2;                /* pour la base d'arrivée */
      }
      TableBin[j]=reste+'0';
   }
 
   /* Utiliser résultat dans TableBin en ASCII avec le bit le moins significatif en 0 */
}

 

[edtdd]--Message édité par tfj57--[/edtdd]


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)