Hexa et chaine
Hexa et chaine
Encore une question idiote du Thyphoon
j'ai une valeur hexa dans une variable
a$="$FFFFFF"
comment je peu la transformer en valeur décimal ?
avec la commande Val() ça ne fonctionne pas
et j'ai pas trouvé de commande comme bin(), Hex() mais qui transformerait en decimal ... Dec() n'existe pas ...
Quel est l'astuce ?
Merci d'avance
j'ai une valeur hexa dans une variable
a$="$FFFFFF"
comment je peu la transformer en valeur décimal ?
avec la commande Val() ça ne fonctionne pas
et j'ai pas trouvé de commande comme bin(), Hex() mais qui transformerait en decimal ... Dec() n'existe pas ...
Quel est l'astuce ?
Merci d'avance
N'oublies pas que CodeArchiv c'est ton ami 

Code : Tout sélectionner
; English forum: http://purebasic.myforums.net/viewtopic.php?t=8828&highlight=
; Author: Froggerprogger
; Date: 23. December 2003
; Some notes:
; -----------
; There's no difference between a hex-value and a decimal value except for the notation.
; The functions that are writing into a file do always request even binary numbers - as
; every function in a programming language - but they don't care if they are notated as
; e.g. (decimal) 32 or $20 or %100000
; So you'll have to parse the string and get the value from it (there it is important,
; that it is notated as a hex-value) and then store this value to your file.
; If you view the file-content with a HEX-Editor, you'll see the values in HEX-notation,
; but they have the same value as the decimal.
; So e.g. you have a string that contains $20, you'll get the decimal value 32 from it
; and store the value 32 to file.
; A Hex-Editor will view it as '20' again, but it's value to calculate with is still 32.
; Here's a routine to get the decimal value from a string that contains Hex-data:
; 23.12.2003 by Froggerprogger
; parses from right to left and retrieves the value of a maximum of 8 chars
; interpretated as a HEX-number or if a non-valid char or the end is reached.
; it works case-insensitive, so 'af' = 'AF'
Procedure GetValueFromHexString(str.s)
If Len(str) = 0
ProcedureReturn -1
EndIf
str = UCase(str)
Protected actCharAsc.l, result.l
Protected strLen.l : strLen = Len(str)
Protected parseAct.l : parseAct = @str + strLen - 1
Protected parseEnd.l : parseEnd = parseStart - 7
Protected posFact.l : posFact = 1
Protected radix.l : radix = 16
actCharAsc = PeekB(parseAct)&$FF
While ((actCharAsc >= 48 And actCharAsc <= 57) Or (actCharAsc >= 65 And actCharAsc <= 70)) And parseAct >= parseEnd
If actCharAsc >= 65
actCharAsc - 7
EndIf
actCharAsc - 48 ; so '0'-'F' has values 0 - 15
result + posFact * actCharAsc
parseAct - 1
posFact * 16
actCharAsc = PeekB(parseAct)&$FF
Wend
ProcedureReturn result
EndProcedure
Debug GetValueFromHexString("(§/346&(=20")
Debug GetValueFromHexString("$7FFffFFf")
Debug GetValueFromHexString("$FFFFFF")
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
-
- Messages : 4312
- Inscription : mer. 28/janv./2004 20:58
- Localisation : Clermont ferrand OU Olsztyn
- Contact :
Moi, j'ai fait ces 2 procedures (vous pouvez en faire une lib, c'est ce que j'ai fait)
Code : Tout sélectionner
ProcedureDLL HexVal(Txt.s) ; Convertir une chaine hexadécimal en valeur numérique
Protected Val.l, n.l, Caractere.w
Txt = LCase(Trim(RemoveString(Txt, "$")))
Val = 0
For n = 0 To Len(Txt) - 1
Caractere = Asc(Mid(Txt, Len(Txt) - n ,1))
If Caractere >= 97 And Caractere <= 102
Val = Val | ((Caractere - 87) << (4 * n))
ElseIf Caractere >= 48 And Caractere <= 57
Val = Val | ((Caractere - 48) << (4 * n))
EndIf
Next
ProcedureReturn Val
EndProcedure
ProcedureDLL BinVal(Txt.s) ; Convertir une chaine binaire en valeur numérique
Protected Val.l, Chiffre.b
Txt = LCase(Trim(RemoveString(Txt, "%")))
Val = 0
For n = 0 To Len(Txt) - 1
Chiffre = Val(Mid(Txt, Len(Txt) - n ,1))
Val = Val | (Chiffre << n)
Next
ProcedureReturn Val
EndProcedure
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?
[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
J'ai ça, trouvé dans CodeArchiv, le fichier s'appelle Bin&Hex_to_Decimal.pb.
Sinon, il me semble que quelqu'un avait posté un truc à ce sujet. (ZapMan, si ma mémoire est bonne).
Code : Tout sélectionner
Procedure HexVal(a$); - Convert a String in hexdecimal-format in numeric value
a$=Trim(UCase(a$))
If Asc(a$)='$'
a$=Trim(Mid(a$,2,Len(a$)-1))
EndIf
Result=0
*adr.BYTE=@a$
For i=1 To Len(a$)
Result<<4
Select *adr\b
Case '0'
Case '1':Result+1
Case '2':Result+2
Case '3':Result+3
Case '4':Result+4
Case '5':Result+5
Case '6':Result+6
Case '7':Result+7
Case '8':Result+8
Case '9':Result+9
Case 'A':Result+10
Case 'B':Result+11
Case 'C':Result+12
Case 'D':Result+13
Case 'E':Result+14
Case 'F':Result+15
Default:i=Len(a$)
EndSelect
*adr+1
Next
ProcedureReturn Result
EndProcedure
; Demo:
Debug HexVal("$12E")
Encore plus court:

Code : Tout sélectionner
; By Nico
Procedure Hex_to_Dec(Hex.s)
chaine$="0123456789ABCDEF"
*Pointeur = @Hex+1
For a= 1 To Len(Hex)-1
valeur = FindString(chaine$, PeekS(*Pointeur,1), 1)
*Pointeur=*Pointeur+1
res= res <<4 | valeur-1
Next
ProcedureReturn res
EndProcedure
Hexadecimal.s="$12ABCDEF"
Debug Hex_to_Dec(Hexadecimal)
Debug $12ABCDEF

Pour les binaires, c'est encore plus simple:

Code : Tout sélectionner
; By Nico
Procedure Bin_to_Dec(Bin.s)
*Pointeur = @Bin+1
For a= 1 To Len(Bin)-1
valeur=PeekB(*Pointeur) & %1
res= res <<1 | valeur
*Pointeur=*Pointeur+1
Next
ProcedureReturn res
EndProcedure
Binaire.s="%10010110111010100101"
Debug Bin_to_Dec(Binaire)
Debug %10010110111010100101

Bonjour Nico
Sauf erreur de ma part :
Ta procedure ne fonctionne pas toujours
exemple :
par contre si tu changes la ligne :
res= res <<4 | valeur-1
par
res= res <<4 + valeur-1
cela semble marcher à tous les coups !
Sauf erreur de ma part :
Ta procedure ne fonctionne pas toujours
exemple :
Code : Tout sélectionner
; By Nico
Procedure Hex_to_Dec(Hex.s)
chaine$="0123456789ABCDEF"
*Pointeur = @Hex+1
For a= 1 To Len(Hex)-1
valeur = FindString(chaine$, PeekS(*Pointeur,1), 1)
*Pointeur=*Pointeur+1
res= res <<4 | valeur-1
Next
ProcedureReturn res
EndProcedure
Hexadecimal.s="$1F"
Debug $1F
Debug Hex_to_Dec(Hexadecimal)
res= res <<4 | valeur-1
par
res= res <<4 + valeur-1
cela semble marcher à tous les coups !
Denis
Bonne Jounée à tous
Bonne Jounée à tous
La doc de PureBasic est peu locace sur la priorité des opérateurs
res= res <<4 | (valeur-1)
mais j'ai fait peu de tests et j'ai pas analysé le code complet.
res= res <<4 | valeur-1 peut aussi être remplacé par- Calcul arithmétique standard avec respect de la priorité des opérateurs et parenthèses : +, -, /, *, and, or, lsl, asl, lsr, asr
res= res <<4 | (valeur-1)
mais j'ai fait peu de tests et j'ai pas analysé le code complet.
Re Bonjour
Le plus court peut être aussi :
et dans le même esprit de simplification
Le plus court peut être aussi :
Code : Tout sélectionner
Procedure Hex_to_Dec(Hex.s)
For a= 1 To Len(Hex)-1
res= res <<4 | FindString("123456789ABCDEF", PeekS(@Hex+a,1), 1)
Next
ProcedureReturn res
EndProcedure
Code : Tout sélectionner
Procedure Bin_to_Dec(Bin.s)
For a= 1 To Len(Bin)-1
res= res <<1 | (PeekB(@Bin+a) & %1)
Next
ProcedureReturn res
EndProcedure
Denis
Bonne Jounée à tous
Bonne Jounée à tous
Bonjour Nico
Je suis d'accord avec toi pour le fait d'être clair dans un développement, mais alors va au bout de ton raisonnement et évite de passer par des pointeurs mémoire et autre rotation de bite qui ne sont clair que pour des gens rompus au language machine !
Je pense que la solution qui suit est plus simple à comprendre pour le commun des mortels dont je fais partie, et tout aussi rapide.
Je souligne par contre ton astuce qui utilise FindString, qui est superbe, et c'est ce qui m'a d'ailleur donné envie de faire cette mise au point.
Une fois condensé et épuré des commentaires le code peut être ramené à cela :
Pour être vraiment honnête j'adore les procédures qui se résument à trois quatre lignes de code bien senties !
Bravo encore Nico !!
Je suis d'accord avec toi pour le fait d'être clair dans un développement, mais alors va au bout de ton raisonnement et évite de passer par des pointeurs mémoire et autre rotation de bite qui ne sont clair que pour des gens rompus au language machine !
Je pense que la solution qui suit est plus simple à comprendre pour le commun des mortels dont je fais partie, et tout aussi rapide.
Je souligne par contre ton astuce qui utilise FindString, qui est superbe, et c'est ce qui m'a d'ailleur donné envie de faire cette mise au point.
Code : Tout sélectionner
Procedure.l Hex2Dec(MotHex.s)
; Répétition pour chacun des caractères du mot hexa
For n=1 To Len(MotHex)
; Extraction du caractère hexa ou Quartet et mise en forme pour la casse !
Quartet.s = UCase(Mid(MotHex,n,1))
; Affectation de sa valeur décimale au quartet. FindString renvoie la position du quartet
;dans la chaine qui se trouve correspondre à sa valeur décimale.
;Pour 0 qui n'est pas dans la chaine FindString renvoit naturellement 0.
ValQuartet.b = FindString("123456789ABCDEF",Quartet,1)
; Calcul de la valeur décimale du mot hexa, à chaque fois que l'on rajoute un quartet à un mot hexa,
; sa valeur précédente est multipliée par 16 plus le nouveau quartet
ValDec.l = ValDec * 16 + ValQuartet
; Répétition jusqu'a la fin du mot hexa
Next
ProcedureReturn ValDec
EndProcedure
Debug $1FAA12
Debug Hex2Dec("$1faa12")
Code : Tout sélectionner
Procedure.l Hex2Dec(MotHex.s)
For n=1 To Len(MotHex)
ValDec.l * 16 + FindString("123456789ABCDEF",UCase(Mid(MotHex,n,1)),1)
Next
ProcedureReturn ValDec
EndProcedure
Debug $1FAA12
Debug Hex2Dec("$1faa12")
Bravo encore Nico !!
Denis
Bonne Jounée à tous
Bonne Jounée à tous