Le forum (ô combien francophone) des utilisateurs de Powerbuilder.





Bonjour,
Je souhaite convertir une chaine hexadécimale en une chaine décimale.
Pour cela j'ai trouvé une fonction, mais elle retourne un long... Aussi je convertis ce long en string lors du retour.
Exemple de chaine hexadécimale à convertir :
885D8CEDF018571E
Résultat décimal attendu : (d'après la calculatrice Windows)
9826164915555555102
La fonction :
[of_hex2long(as_hex) returns a string] string ls_hex integer i,length long result = 0 length = len(as_hex) ls_hex = Upper(as_hex) FOR i = 1 to length result += & (Pos ('123456789ABCDEF', mid(ls_hex, i, 1)) * & ( 16 ^ ( length - i ) )) NEXT RETURN string(result) // Retourne : "-1861025793"
Si je tente une conversion pas à pas, voici les résultats :
8 en héxadécimal devient 8 en décimal. C'est OK.
88 en héxadécimal devient 136 en décimal. C'est OK.
885 en héxadécimal devient 2 181 en décimal. C'est OK.
885D en héxadécimal devient 34 909 en décimal. C'est OK.
885D8 en héxadécimal devient 558 552 en décimal. C'est OK.
885D8C en héxadécimal devient 8 936 844 en décimal. C'est OK.
885D8CE en héxadécimal devient 142 989 518 en décimal. C'est OK.
885D8CED en héxadécimal devient -2 007 134 995 en décimal. C'est pas OK, il faut obtenir 228 783 230.
Il y a donc quelque chose que je n'ai pas du comprendre dans la conversion d'un hexadécimal en décimal.
Avez-vous une idée du problème, s'il vous plait ?
Dernière modification par Nyphel (18-08-2008 13:30:39)
Hors ligne







Nyphel a écrit:
Bonjour,
Je souhaite convertir une chaine hexadécimale en une chaine décimale.
Pour cela j'ai trouvé une fonction, mais elle retourne un long... Aussi je convertis ce long en string lors du retour.
Exemple de chaine hexadécimale à convertir :
4417123456789112FFFF
Résultat décimal attendu : (d'après la calculatrice Windows) (Faux)
4906410335041786130 = 4417123456789112FFFF
La fonction :Code: pb
[of_hex2long(as_hex) returns a string] string ls_hex integer i,length long result = 0 length = len(as_hex) ls_hex = Upper(as_hex) FOR i = 1 to length result += & (Pos ('123456789ABCDEF', mid(ls_hex, i, 1)) * & ( 16 ^ ( length - i ) )) NEXT RETURN string(result) // Retourne : "-1861025793"
Il y a donc quelque chose que je n'ai pas du comprendre dans la conversion d'un hexadécimal en décimal.
Avez-vous une idée du problème, s'il vous plait ?
Pour convertir un hexadécimal en décimal il faut suivre la règle :
J'en ai fait une image parce que sinon c'est mal aligné ^^
Bref je pense que PB est limité dans le calcul d'aussi grands chiffres parce que même la calculatrice window de ne peut pas le calculer du premier coup, il faut passer les additions unes à unes.
Ça fait quand même : 321 trilliard 546 trillion 507 billiard 717 billion 298 milliard 495 million 881 mille 215
Dernière modification par Nephtis (18-08-2008 13:27:33)
Hors ligne





Oups je viens d'éditer le premier post, donc les lecteurs risquent de ne pas tout comprendre...
A vrai dire j'en arrivais à la conclusion que le nombre était trop grand pour être stocké dans un long, ce qui du coup retournerait -1.
Il semble donc que je ne puisse même pas faire des addition successives, puisque le résultat final ne rentrera pas dans un long. Ayant déjà eu ce genre de soucis, j'avais stocké mon résultat dans du string puisque je ne travaille pas sur le résultat : je me contente de le stocker en base de données.
Seulement voilà : je ne vois pas comment faire ce calcul en utilisant du string.
PS : c'est quel logiciel que tu utilises pour ce calcul ?
----------------------------------------------------------------------------------------
Long
32-bit signed integers, from -2147483648 to +2147483647.
Using literals Use literals as for integers, but longer numbers are permitted.
LongLong
64-bit signed integers, from -9223372036854775808 to 9223372036854775807.
Using literals Use literals as for integers, but longer numbers are permitted.
Du coup j'ai modifié ma fonction comme suit :
string ls_hex integer i,length longlong result = 0 length = len(as_hex) ls_hex = Upper(as_hex) FOR i = 1 to length result += & (Pos ('123456789ABCDEF', mid(ls_hex, i, 1)) * & ( 16 ^ ( length - i ) )) NEXT RETURN string(result)
Toutefois le résultat demeure inchangé... Que j'utilise un Long, un LongLong ou même un Double.
Dernière modification par Nyphel (18-08-2008 13:44:47)
Hors ligne







Nyphel a écrit:
Oups je viens d'éditer le premier post, donc les lecteurs risquent de ne pas tout comprendre...
A vrai dire j'en arrivais à la conclusion que le nombre était trop grand pour être stocké dans un long, ce qui du coup retournerait -1.
Il semble donc que je ne puisse même pas faire des addition successives, puisque le résultat final ne rentrera pas dans un long. Ayant déjà eu ce genre de soucis, j'avais stocké mon résultat dans du string puisque je ne travaille pas sur le résultat : je me contente de le stocker en base de données.
Seulement voilà : je ne vois pas comment faire ce calcul en utilisant du string.
PS : c'est quel logiciel que tu utilises pour ce calcul ?
----------------------------------------------------------------------------------------Long
32-bit signed integers, from -2147483648 to +2147483647.
Using literals Use literals as for integers, but longer numbers are permitted.
LongLong
64-bit signed integers, from -9223372036854775808 to 9223372036854775807.
Using literals Use literals as for integers, but longer numbers are permitted.Du coup j'ai modifié ma fonction comme suit :
Code: pb
string ls_hex integer i,length longlong result = 0 length = len(as_hex) ls_hex = Upper(as_hex) FOR i = 1 to length result += & (Pos ('123456789ABCDEF', mid(ls_hex, i, 1)) * & ( 16 ^ ( length - i ) )) NEXT RETURN string(result)Toutefois le résultat demeure inchangé.
Pour faire une addition de chaînes de caractères, PB ne va t'il pas faire une conversion implicite de la chaîne de caractère dans une variable de type numérique pour ensuite la retransformer en variable de type String?
Fait l'essai avec deux chaines bien longues et regarde le résultat que PB te donnes (aujourd'hui c'est jour de congé pour moi, j'ai pas PB sous la main )
PS : Le logiciel que j'utilise pour faire ce calcul est sous copyright (c'est mon cerveau
)
Hors ligne





string ls_chaine_A string ls_chaine_B string ls_chaine_C ls_chaine_A = '123000000000000000001' ls_chaine_B = '000456000000000000002' ls_chaine_C = ls_chaine_A + ls_chaine_B messagebox('', ls_chaine_C) // ls_chaine_C = 123000000000000000001000456000000000000002
Et oui, ça concatène au lieu d'additionner... Il faudrait carrément ré-implémenter une addition de chaines de caractères.
Merci quand même d'avoir pris du temps pour ça ;)
Hors ligne







Nyphel a écrit:
Code: pb
string ls_chaine_A string ls_chaine_B string ls_chaine_C ls_chaine_A = '123000000000000000001' ls_chaine_B = '000456000000000000002' ls_chaine_C = ls_chaine_A + ls_chaine_B messagebox('', ls_chaine_C) // ls_chaine_C = 123000000000000000001000456000000000000002
Et oui, ça concatène au lieu d'additionner... Il faudrait carrément ré-implémenter une addition de chaines de caractères.
Merci quand même d'avoir pris du temps pour ça ;)
Y a pas de quoi mais là je n'ai pas trop d'idée pour ce calcul à part peut être passer par ton SGBD (on sait jamais)
Faudra attendre les grands gourous pour voir si ils ont pas déjà été confrontés à ça, moi je ne suis qu'un petit padawan
Hors ligne





En fin de compte je me suis trompé, je ne dois pas convertir mon hexadecimal en décimal :-D
Je laisse le sujet ouvert, il pourrait intéresser quelqu'un.
Hors ligne



Il y a peut-être moyen d'éviter le recours à une librairie externe spécialisée dans les calculs sur les grands nombres : le type "decimal", de préférence avec un version récente de PowerBuilder.
PB v10.5 a écrit:
Decimal datatype support
In previous releases of PowerBuilder, the Decimal datatype in PowerScript supported up to 18 digits. In PowerBuilder 10.5, the Decimal datatype supports up to 28 digits.
Hors ligne





Moi je ne peux pas tester, je suis en PB 10.2.0 build 8075... Mais ça semble être la solution !
Hors ligne