[vb6] convertir une variable double en large int

Ton dernièr code marche avec certains nombres et d’autre moins :smiley:

avec 5754147691 >> low=1459180395 et high=1 (c’est bon)
avec 1754147691 >> low=1459180395 et high=0 (c’est bon, pas besoin du poids fort)
avec 11254567255 >> low=-1630334633 et high=3 (c’est pas bon, normalement low=2664632663 et high=2)
avec 3254567255 >> low=-1040400041 et high=1 (c’est pas bon, normalement low=3254567255 et high=0)
avec 4294967295 >> low=1 et high=-1 (c’est pas bon, normalement low=4294967295 et high=0)

Manque plus grand chose je pense la :smiley:

là c’est un peu normal: les Long sont signés, donc pour les grand nombres, si tu converti en hex avec la calculatrice: tu obtient
en 64 bits sous calc.exe
FFFFFFFF9ED31157
donc en 32 bits 9ED31157 ce qui correspond au résultat attendu. tu retrouve le bon résultat en faisant 4294967296+(la valeur négative) si le nombre est négative pour repasser en no-signé.
le plus simple serait d’utiliser des entier non-signés, mais est-ce que ça existe en VB?

là c’est un mystère :smiley: Note: j’ai inversé low et High dans mon code, donc si c’est le high qui vaut 1 au lieu de zéro ça s’explique, c’est peut-être une erreur d’arrondi vu qu’on calcule en Double.ça veut dire qu’il faudrait patcher un peu :confused: si le reste (donc le low) est négatif et que c’est incohérent, on ajoute 4294967296 au reste et on enlève 1 au high…

En fait il faut faire le test sur le résultat en Double et pas en Long puisque le Long devient négatif s’il est trop grand:


Dim l As Long
Dim h As Long
Dim x As Double
dim reste as Double
h = x / (4294967296#)
reste = x - (h * 4294967296#)
' patch si erreur arrondi
if (reste <0) then 
 reste = reste + 4294967296#
 h = h -1
end if
l = reste

Merci à Karlkox quand même, :super: j’ai essayé de comprendre ton code, et la copie mémoire m’a servi pour les tests bit à bit. on doit pouvoir s’en sortir en extrayant l’exposant et avec des décalage de bits, mais l’algo est un peu hard…

edit: une petite page de doc de microsoft qui peut être intéressante:
64 Bits computing in VB

Ton dernier code avec le path provoque un dépassement de capacité avec la valeur double “11254567255” sur “l=reste”. J’essaie aussi de mon côté de trouver quelque chose mais les algos c’est pas trop mon truc (pas du tout même) :smiley:

Je tiens à vous remercier beaucoup tout les deux pour cette aide et j’espère qu’il existe une solution qui fonctionne avec toutes les valeurs double possibles avec vb6 car ça sera la seule trouvable sur le net et ça pourra dépanner d’autres personnes qui sont bloquées tout comme moi :wink:

Oublie mon patch, j’avais du fumer la moquette:
non simplement quand le reste est négatif, son contenu binaire est ok, mais la partie high a juste 1 de trop, alors c’est un peu di bidouillage, mais dans ce cas, on enlève un à high, et c’est ok:


h = x / (4294967296#)
l = x - (h * 4294967296#)
'patch si erreur arrondi
If (l < 0) Then
    h = h - 1
End If
MsgBox "x=" & x
MsgBox "h=" & Hex$(h)
MsgBox "l=" & Hex$(l)

et pour le test suivant:
4294967295 >> renvoie low=-1 qui vaut FFFFFF en hexa et high=0

là ça commence d’être bon :slight_smile:

C’est presque parfait effectivement, il manque plus grand chose, le seul problème restant est la reconversion du nombre hexadecimal en decimal non signé car dans vb6 malheuresement je pense qu’il n’existe pas de type semblable à long mais non signé (un type ULong) comme en .net apparement.

Du coup avec vb CLng("&h ") donne -1630334633 alors qu’avec calc.exe ça donne

2664632663? j’imagine :smiley:
Bon il me manque un peu la fin, pour comprendre :smiley:

Mais ça me paraît normal, comme tes Long sont signés tu ne peut pas avoir cette valeur dans un Long, mais la représentation mémoire dans le Long reste bonne, puisque si tu reconverti ton nombre négatif en HEXA tu obtient bien le bon résultat.

Si tu veux tu peux décrire l’ensemble du problème (codage-décodage depuis et vers du Double)

exact! j’ai compris mon erreur, en clair il affiche le signe mais en s’en fou :smiley:

Merci beaucoup en tout cas du coup de main :wink:

Voila le code complet et résolu du problème que j’avais si ça peut servir à quelqu’un :wink:

Public Function fctnSetFilePointerPos(FilePointer As Long, ByVal DistanceToMove As Double) As Long


    'Declarations
    
    Dim lngLow As Long
    Dim lngHigh As Long

    
    'Define 'low byte' and 'high byte'
    
    lngHigh = DistanceToMove / (4294967296#)
    lngLow = DistanceToMove - (lngHigh * 4294967296#)

    If (lngLow < 0) Then
    
       lngHigh = lngHigh - 1
       
    End If
    

    'Move pointer in opened file
    
    fctnSetFilePointerPos = SetFilePointer(FilePointer, lngLow, lngHigh, 0)


End Function

je t’en prie.
:super: