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

 


 Mot :   Pseudo :  
 
 Page :   1  2
Page Suivante
Auteur Sujet :

Passer d'une chaine de chiffre à une chaine de bit???

n°50628
tfj57
Posté le 02-08-2001 à 13:30:09  profilanswer
 

Reprise du message précédent :
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]

mood
Publicité
Posté le 02-08-2001 à 13:30:09  profilanswer
 

n°50732
TotOOntHeM​ooN
Posté le 02-08-2001 à 17:26:21  profilanswer
 

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 ...

n°50782
TotOOntHeM​ooN
Posté le 03-08-2001 à 09:12:07  profilanswer
 

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)

n°50784
TotOOntHeM​ooN
Posté le 03-08-2001 à 09:38:49  profilanswer
 

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.

n°50794
TotOOntHeM​ooN
Posté le 03-08-2001 à 10:19:15  profilanswer
 

Bon, la prochaine fois je réfléchirais avant de dire une connerie... Il faut bien mettre 1, pour etre sur du resultat.

n°50797
Carbon_14
Posté le 03-08-2001 à 10:26:50  profilanswer
 

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

n°50803
Mara's dad
Yes I can !
Posté le 03-08-2001 à 10:57:44  profilanswer
 

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.


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
n°50809
Carbon_14
Posté le 03-08-2001 à 11:18:24  profilanswer
 

: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: .

n°50863
TotOOntHeM​ooN
Posté le 03-08-2001 à 13:09:49  profilanswer
 

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 !

n°50866
Carbon_14
Posté le 03-08-2001 à 13:21:02  profilanswer
 

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 ?  :??:

mood
Publicité
Posté le 03-08-2001 à 13:21:02  profilanswer
 

n°50871
TotOOntHeM​ooN
Posté le 03-08-2001 à 13:31:43  profilanswer
 

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 !

n°50875
Carbon_14
Posté le 03-08-2001 à 13:57:09  profilanswer
 

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..

n°50889
TotOOntHeM​ooN
Posté le 03-08-2001 à 14:30:55  profilanswer
 

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

n°50908
nur
Posté le 03-08-2001 à 14:47:26  profilanswer
 

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

n°50912
Carbon_14
Posté le 03-08-2001 à 14:57:36  profilanswer
 

TotOOntHeMooN  
La calculatrice Windows donne 0100 1101 0010 Bin pour 1234 Décimal ou 4D2 Hexa.
C'est donc tout bon.   :jap:

n°50916
TotOOntHeM​ooN
Posté le 03-08-2001 à 15:02:36  profilanswer
 

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++ ?

n°50919
TotOOntHeM​ooN
Posté le 03-08-2001 à 15:06:56  profilanswer
 

Tu fais confiance à la calculatrice windows CARBON_14 ? :crazy:  
Bon, ça se tente, non ?

n°50935
Carbon_14
Posté le 03-08-2001 à 15:35:23  profilanswer
 

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:

n°50937
TotOOntHeM​ooN
Posté le 03-08-2001 à 15:41:49  profilanswer
 

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 ?

n°50945
Carbon_14
Posté le 03-08-2001 à 16:04:16  profilanswer
 

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 :??: ...

n°50953
TotOOntHeM​ooN
Posté le 03-08-2001 à 16:22:17  profilanswer
 

OK, bon scan, bon weekend et a lundi.  
Avec une solution...

n°50955
TotOOntHeM​ooN
Posté le 03-08-2001 à 16:23:16  profilanswer
 

Pour le soft, essai avec PowerPoint...

n°51020
HelloWorld
Salut tout le monde!
Posté le 03-08-2001 à 23:54:12  profilanswer
 

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)


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
mood
Publicité
Posté le   profilanswer
 

 Page :   1  2
Page Suivante

Aller à :
Ajouter une réponse
 

Sujets relatifs
ASP => Decouper une chaine[Calques] Passer d'un calque a un autre... C'est possible ?
je ne retrouve la fct javascript pour transformer un chaine en chiffre[PHP / Javascript] Problème pour passer des paramètres!
[HTML] comment pâsser un parametre dans une frame ?php attache un chaine sur plusieurs lignes?
Pb Requete ACCESS 97 sur une chaine de caractèresPHP // passer un tableau en argument
decoupe un chaine avec un delimiteur en javascript =>tableau?? 
Plus de sujets relatifs à : Passer d'une chaine de chiffre à une chaine de bit???


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR