variable quad en Hexa : BUG ? [RESOLU]

Archive.
Fanator
Messages : 20
Inscription : jeu. 19/avr./2007 8:14

variable quad en Hexa : BUG ? [RESOLU]

Message par Fanator »

Bonjour à tous.
Je poste mon bout de programme, il y a peut-être un bug.
Version PureBasic utilisée : V4.10 béta 2
Peut-être me suis-je trompé, si quelqu'un peut y regarder...

Code : Tout sélectionner

Dim tab(64)
b.q=9223372036854770    ; cette valeur passe
; b.q=9223372036854771    ; tout ce qui est supérieur à la valeur précédente
; b.q=9223372036854775807 ; ne passe pas correctement à la sortie du programme
x.q=0
Debug "b = " + StrQ(b) + ", en Hexadécimal =" + HexQ(b)
c$ = HexQ(b)
  ; décomposition de la variable hexadécimale
For i= 1 To Len(c$)
  Select Mid(c$,i,1)
    Case "0","1","2","3","4","5","6","7","8","9"
      tab(i)=Val(Mid(c$,i,1))
    Case "A"
      tab(i)=10
    Case "B"
      tab(i)=11
    Case "C"
      tab(i)=12
    Case "D"
      tab(i)=13
    Case "E"
      tab(i)=14
    Case "F"
      tab(i)=15
  EndSelect
  Debug "Pos" + Str(i) + "__" + Str(tab(i))
Next i

For i=1 To Len(c$)
  x = x + tab(i)*Pow(16,Len(c$)-i)
Next i
Debug x                                   ; x doit être égal à b
Debug HexQ(x) + " en décimal =" + StrQ(x)

Debug ""
End

Fanator
Dernière modification par Fanator le mar. 31/juil./2007 20:34, modifié 1 fois.
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

en purebasic les entiers sont 'signés' et donc au delà d'une certaine valeur (127 pour un .b etc...) on passe en négatif. j'ai pas regardé plus que çà ton code mais ton problème semble être lié.
Image
Fanator
Messages : 20
Inscription : jeu. 19/avr./2007 8:14

Message par Fanator »

@Flype :
Je ne suis pas tout à fait d'accord.
Pow(2,31)-1=2147483647 valeur maxi pour un long : valeur correcte
Pow(2,63)-1 doit être égal à 9223372036854775807 valeur maxi pour un quad.
Pow(2,63)-1= $7FFF FFFF FFFF FFFF, il suffit de controler avec la calculatrice de windows ou autre.
Donc je pense qu'il y a un problème à partir d'une certaine valeur (voir le code)



Fanator
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

L'erreur n'est pas dans HexQ()
Elle est dans l'opération

Code : Tout sélectionner

x + n * Pow(a, b) ; Erreur de bit de parité
Une erreur de bit de parité sûrement conséquente à Pow().

La solution actuelle consiste juste à 'sortir' Pow de ton calcul en décomposant ce calcul.
Tu stockes Pow(a, b) dans un Quad nommé Q.Q par exemple et tu effectues en suite ton calcul:

Code : Tout sélectionner

Q.Q = Pow(a, b)
x + n * Q
Sinon, pour ta part, tu utilises une puissance de 2 (16 = Pow(2, 4) ) alors ne t'embête pas avec des multiplications et des puissances : tu fais travailler le CPU pour rien!

Utilises les décalages et opé logiques, c'est carrément plus simple pour toi et pour ton CPU. J'ai remanié ton code:

Code : Tout sélectionner

Dim tab.Q(64)

;b.q=9223372036854770    ; cette valeur passe 
; b.q=9223372036854771    ; tout ce qui est supérieur à la valeur précédente 
; b.q=9223372036854774    ; BEN NON PUISQUE LA VALEUR CI-CONTRE FONCTIONNE !
; b.q=9223372036854775807 ; ne passe pas correctement à la sortie du programme 
x.q=0 
Debug "b = " + StrQ(b) + ", en Hexadécimal =" + HexQ(b) 
c$ = HexQ(b) 
  ; décomposition de la variable hexadécimale 
For i= 1 To Len(c$) 

  Select Mid(c$,i,1) 
    Case "0","1","2","3","4","5","6","7","8","9" 
      tab(i)=Val(Mid(c$,i,1)) 
    Case "A" 
      tab(i)=10 
    Case "B" 
      tab(i)=11 
    Case "C" 
      tab(i)=12 
    Case "D" 
      tab(i)=13 
    Case "E" 
      tab(i)=14 
    Case "F" 
      tab(i)=15 
  EndSelect 
  Debug "Pos" + Str(i) + "__" + Hex(tab(i)) 
Next i 

;For i=1 To Len(c$) 
;  x = x + tab(i)* Pow(16,Len(c$)-i) 
;Next i 

; ça doit être au moins 5 fois plus rapide en cycle d'horloge
For i = 1 To Len(c$)
  x << 4 ; Décaler de 4 bits à gauche c'est multiplier par 16
  x | Tab(i) : Les champs de bits entre x et Tab(i) ne se 
  ;                croisent pas dans l'addition donc opération OU
Next

Debug x                                   ; x doit être égal à b 
Debug StrQ(x) + " en hexadécimal =" + HexQ(x) 

Debug "" 
End 
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

tu as parfaitement raison ollivier.

Code : Tout sélectionner

Q.Q = Pow(a, b)
x + n * Q
la raison précise est Pow() prends deux flottants comme arguments et renvoie un flottant (.f)

et le compilateur purebasic va faire des transformations de type qui peuvent provoquer des problèmes d'arrondis. Or, stocker le résultat de Pow() dans une variable .q force le compilateur à faire la multiplication avec un quad au lieu d'un float.
Image
Fanator
Messages : 20
Inscription : jeu. 19/avr./2007 8:14

Message par Fanator »

@Flype
@Ollivier


J'avais fini par trouver les floats à propos de Pow() dans l'aide, mais vous avez trouvé la réponse.
C'est bien mon bout de programme qui était bogué pas PureBasic.
Je vous remercie tous les 2 pour vous être pencher sur mon problème.


Bonne soirée à tous !
Répondre