comment creer / parser un entier signe negatif sur n octets ?
6 réponses
Thomas Harding
Bonjour,
je sèche sur un algo :)
Je voudrais, d'une part créer un entier signé (éventuellement négatif)
sur 4 octets, à partir d'un nombre décimal, et d'autre part parser
un entier signé encodé sur 4 octets pour en faire un nombre décimal
(éventuellement négatif).
J'y arrive avec un nombre positif:
##############################################
// {{{ _interpretInteger($value)
protected function _interpretInteger($value) {
// they are _signed_ integers
$negative = false;
$value_parsed = 0;
if ($value >= 2147483648 || $value <= -2147483648) {
trigger_error(_("Values must be between \
-2147483648 and 2147483648: assuming '0'"),E_USER_WARNING);
return chr(0x00).chr(0x00).chr(0x00).chr(0x00);
}
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Olivier Miakinen
Je voudrais, d'une part créer un entier signé (éventuellement négatif) sur 4 octets, à partir d'un nombre décimal, et d'autre part parser un entier signé encodé sur 4 octets pour en faire un nombre décimal (éventuellement négatif).
J'ai d'abord failli t'envoyer sur <http://fr.php.net/sscanf> mais après lecture plus attentive je vois que ce n'est pas le cas.
J'y arrive avec un nombre positif:
À la limite, vu que les entiers positifs entre 2147483648 et 4294967295 sont représentés de façon exacte par les flottants (pourvu que tu sois sur une machine où les flottants sont sur 64 bits ou plus), tu peux faire les calculs pour des nombres positifs, et ajouter ou soustraire 4294967296 selon le cas.
############################################## // {{{ _interpretInteger($value) protected function _interpretInteger($value) { // they are _signed_ integers $negative = false; $value_parsed = 0;
for ($i = strlen($value) ; $i > 0 ; $i --)
Je n'aime pas beaucoup parcourir les tableaux du plus grand indice au plus petit, mais bon, c'est ton choix. Vu comment tu fais, tu devras en plus faire « - 1 » à chaque utilisation de l'indice. Par ailleurs, j'ai l'impression que ta fonction suppose un ordre de rangement « little endian », ce qui la rend un peu spécifique au type de machine.
Personnellement, je commencerais par transformer la chaîne en tableau de quatre valeurs, ordonnées en « big endian » comme dans la plupart des protocoles réseau.
if ($i == strlen($value)) if (ord($value[strlen($value) - $i]) > 0x80)
Tu as une erreur ici : le bit de signe est mis pour une valeur supérieure *ou égale* à 0x80. Il vaudrait mieux utiliser un masque binaire, ce qui serait à la fois plus clair et moins générateur d'erreurs.
Et là tu as une autre erreur : tu positionnes le flag $negative, mais sans récupérer la valeur $value_parsed.
else $value_parsed += pow(256,($i - 1))
Oh, quelle horreur ! Je me demande combien de fois l'opération flottante pow() est plus coûteuse que les opérations binaires de décalage. Au moins 1000 fois, je dirais. Probablement beaucoup plus.
Ah ? Tous les calculs que tu as faits avec des exponentielles sont ignorés quand le nombre est négatif, et tu copies juste le string tel quel ? Pas étonnant que cela ne marche pas.
################################################### // {{{ _integerBuild ($integer) protected function _integerBuild ($value) {
if ($value >= 2147483648 || $value <= -2147483648) {
Encore une erreur d'inégalité. Ici tu refuses la valeur -2147483648, qui est pourtant valide. Par ailleurs, ta comparaison avec +2147483648 se fait en flottant.
if ($value > 2147483647 || $value < -2147483648) {
trigger_error(_("Values must be between -2147483648 and 2147483648: assuming '0'"),E_USER_WARNING);
Mais qui peut me donner la solution pour un nombre négatif ?
Si j'ai le temps je te donnerai une solution générale, pour les nombres positifs comme négatifs. Sinon, et si personne d'autre ne le fait, tu peux toujours suivre le conseil que je te donnais au début :
1) string -> integer Utilise ta fonction pour les nombres positifs (de 0 à 4294967295), puis soustrais 4294967296 si le résultat est supérieur ou égal à 2147483648.
2) integer -> string Ajoute 4294967296 si le nombre est négatif, puis utilise ta fonction pour les nombres positifs (de 0 à 4294967295).
-- Olivier Miakinen Troll du plus sage chez les conviviaux : le nouveau venu, avec son clan, s'infiltre dans les groupes de nouvelles. (3 c.)
Je voudrais, d'une part créer un entier signé (éventuellement négatif)
sur 4 octets, à partir d'un nombre décimal, et d'autre part parser
un entier signé encodé sur 4 octets pour en faire un nombre décimal
(éventuellement négatif).
J'ai d'abord failli t'envoyer sur <http://fr.php.net/sscanf> mais après
lecture plus attentive je vois que ce n'est pas le cas.
J'y arrive avec un nombre positif:
À la limite, vu que les entiers positifs entre 2147483648 et 4294967295
sont représentés de façon exacte par les flottants (pourvu que tu sois
sur une machine où les flottants sont sur 64 bits ou plus), tu peux
faire les calculs pour des nombres positifs, et ajouter ou soustraire
4294967296 selon le cas.
##############################################
// {{{ _interpretInteger($value)
protected function _interpretInteger($value) {
// they are _signed_ integers
$negative = false;
$value_parsed = 0;
for ($i = strlen($value) ; $i > 0 ; $i --)
Je n'aime pas beaucoup parcourir les tableaux du plus grand indice au
plus petit, mais bon, c'est ton choix. Vu comment tu fais, tu devras en
plus faire « - 1 » à chaque utilisation de l'indice. Par ailleurs, j'ai
l'impression que ta fonction suppose un ordre de rangement « little
endian », ce qui la rend un peu spécifique au type de machine.
Personnellement, je commencerais par transformer la chaîne en tableau de
quatre valeurs, ordonnées en « big endian » comme dans la plupart des
protocoles réseau.
if ($i == strlen($value))
if (ord($value[strlen($value) - $i]) > 0x80)
Tu as une erreur ici : le bit de signe est mis pour une valeur
supérieure *ou égale* à 0x80. Il vaudrait mieux utiliser un masque
binaire, ce qui serait à la fois plus clair et moins générateur d'erreurs.
Et là tu as une autre erreur : tu positionnes le flag $negative, mais
sans récupérer la valeur $value_parsed.
else
$value_parsed += pow(256,($i - 1))
Oh, quelle horreur ! Je me demande combien de fois l'opération flottante
pow() est plus coûteuse que les opérations binaires de décalage. Au
moins 1000 fois, je dirais. Probablement beaucoup plus.
Ah ? Tous les calculs que tu as faits avec des exponentielles sont
ignorés quand le nombre est négatif, et tu copies juste le string tel
quel ? Pas étonnant que cela ne marche pas.
###################################################
// {{{ _integerBuild ($integer)
protected function _integerBuild ($value) {
if ($value >= 2147483648 || $value <= -2147483648) {
Encore une erreur d'inégalité. Ici tu refuses la valeur -2147483648, qui
est pourtant valide. Par ailleurs, ta comparaison avec +2147483648 se
fait en flottant.
if ($value > 2147483647 || $value < -2147483648) {
trigger_error(_("Values must be between
-2147483648 and 2147483648: assuming '0'"),E_USER_WARNING);
Mais qui peut me donner la solution pour un nombre négatif ?
Si j'ai le temps je te donnerai une solution générale, pour les nombres
positifs comme négatifs. Sinon, et si personne d'autre ne le fait, tu
peux toujours suivre le conseil que je te donnais au début :
1) string -> integer
Utilise ta fonction pour les nombres positifs (de 0 à 4294967295),
puis soustrais 4294967296 si le résultat est supérieur ou égal à
2147483648.
2) integer -> string
Ajoute 4294967296 si le nombre est négatif, puis utilise ta fonction
pour les nombres positifs (de 0 à 4294967295).
--
Olivier Miakinen
Troll du plus sage chez les conviviaux : le nouveau venu, avec
son clan, s'infiltre dans les groupes de nouvelles. (3 c.)
Je voudrais, d'une part créer un entier signé (éventuellement négatif) sur 4 octets, à partir d'un nombre décimal, et d'autre part parser un entier signé encodé sur 4 octets pour en faire un nombre décimal (éventuellement négatif).
J'ai d'abord failli t'envoyer sur <http://fr.php.net/sscanf> mais après lecture plus attentive je vois que ce n'est pas le cas.
J'y arrive avec un nombre positif:
À la limite, vu que les entiers positifs entre 2147483648 et 4294967295 sont représentés de façon exacte par les flottants (pourvu que tu sois sur une machine où les flottants sont sur 64 bits ou plus), tu peux faire les calculs pour des nombres positifs, et ajouter ou soustraire 4294967296 selon le cas.
############################################## // {{{ _interpretInteger($value) protected function _interpretInteger($value) { // they are _signed_ integers $negative = false; $value_parsed = 0;
for ($i = strlen($value) ; $i > 0 ; $i --)
Je n'aime pas beaucoup parcourir les tableaux du plus grand indice au plus petit, mais bon, c'est ton choix. Vu comment tu fais, tu devras en plus faire « - 1 » à chaque utilisation de l'indice. Par ailleurs, j'ai l'impression que ta fonction suppose un ordre de rangement « little endian », ce qui la rend un peu spécifique au type de machine.
Personnellement, je commencerais par transformer la chaîne en tableau de quatre valeurs, ordonnées en « big endian » comme dans la plupart des protocoles réseau.
if ($i == strlen($value)) if (ord($value[strlen($value) - $i]) > 0x80)
Tu as une erreur ici : le bit de signe est mis pour une valeur supérieure *ou égale* à 0x80. Il vaudrait mieux utiliser un masque binaire, ce qui serait à la fois plus clair et moins générateur d'erreurs.
Et là tu as une autre erreur : tu positionnes le flag $negative, mais sans récupérer la valeur $value_parsed.
else $value_parsed += pow(256,($i - 1))
Oh, quelle horreur ! Je me demande combien de fois l'opération flottante pow() est plus coûteuse que les opérations binaires de décalage. Au moins 1000 fois, je dirais. Probablement beaucoup plus.
Ah ? Tous les calculs que tu as faits avec des exponentielles sont ignorés quand le nombre est négatif, et tu copies juste le string tel quel ? Pas étonnant que cela ne marche pas.
################################################### // {{{ _integerBuild ($integer) protected function _integerBuild ($value) {
if ($value >= 2147483648 || $value <= -2147483648) {
Encore une erreur d'inégalité. Ici tu refuses la valeur -2147483648, qui est pourtant valide. Par ailleurs, ta comparaison avec +2147483648 se fait en flottant.
if ($value > 2147483647 || $value < -2147483648) {
trigger_error(_("Values must be between -2147483648 and 2147483648: assuming '0'"),E_USER_WARNING);
Mais qui peut me donner la solution pour un nombre négatif ?
Si j'ai le temps je te donnerai une solution générale, pour les nombres positifs comme négatifs. Sinon, et si personne d'autre ne le fait, tu peux toujours suivre le conseil que je te donnais au début :
1) string -> integer Utilise ta fonction pour les nombres positifs (de 0 à 4294967295), puis soustrais 4294967296 si le résultat est supérieur ou égal à 2147483648.
2) integer -> string Ajoute 4294967296 si le nombre est négatif, puis utilise ta fonction pour les nombres positifs (de 0 à 4294967295).
-- Olivier Miakinen Troll du plus sage chez les conviviaux : le nouveau venu, avec son clan, s'infiltre dans les groupes de nouvelles. (3 c.)
Marc
Thomas Harding wrote:
Bonjour, je sèche sur un algo :)
Je voudrais, d'une part créer un entier signé (éventuellement négatif) sur 4 octets, à partir d'un nombre décimal, et d'autre part parser un entier signé encodé sur 4 octets pour en faire un nombre décimal (éventuellement négatif).
ce n'est pas le travail de pack, unpack ?
Thomas Harding wrote:
Bonjour,
je sèche sur un algo :)
Je voudrais, d'une part créer un entier signé (éventuellement négatif)
sur 4 octets, à partir d'un nombre décimal, et d'autre part parser
un entier signé encodé sur 4 octets pour en faire un nombre décimal
(éventuellement négatif).
Je voudrais, d'une part créer un entier signé (éventuellement négatif) sur 4 octets, à partir d'un nombre décimal, et d'autre part parser un entier signé encodé sur 4 octets pour en faire un nombre décimal (éventuellement négatif).
ce n'est pas le travail de pack, unpack ?
Vincent Lascaux
Je voudrais, d'une part créer un entier signé (éventuellement négatif) sur 4 octets, à partir d'un nombre décimal, et d'autre part parser un entier signé encodé sur 4 octets pour en faire un nombre décimal (éventuellement négatif).
Je voudrais, d'une part créer un entier signé (éventuellement négatif)
sur 4 octets, à partir d'un nombre décimal, et d'autre part parser
un entier signé encodé sur 4 octets pour en faire un nombre décimal
(éventuellement négatif).
Je voudrais, d'une part créer un entier signé (éventuellement négatif) sur 4 octets, à partir d'un nombre décimal, et d'autre part parser un entier signé encodé sur 4 octets pour en faire un nombre décimal (éventuellement négatif).
À la limite, vu que les entiers positifs entre 2147483648 et 4294967295 sont représentés de façon exacte par les flottants (pourvu que tu sois sur une machine où les flottants sont sur 64 bits ou plus), tu peux faire les calculs pour des nombres positifs, et ajouter ou soustraire 4294967296 selon le cas.
C'est indifféremment sur du 32 ou 64bits :-/
############################################## // {{{ _interpretInteger($value) protected function _interpretInteger($value) { // they are _signed_ integers $negative = false; $value_parsed = 0;
for ($i = strlen($value) ; $i > 0 ; $i --)
Je n'aime pas beaucoup parcourir les tableaux du plus grand indice au plus petit, mais bon, c'est ton choix. Vu comment tu fais, tu devras en plus faire « - 1 » à chaque utilisation de l'indice. Par ailleurs, j'ai l'impression que ta fonction suppose un ordre de rangement « little endian », ce qui la rend un peu spécifique au type de machine.
c'est du big endian:
RFC 2910:
Every integer in this encoding MUST be encoded as a signed integer using two's-complement binary encoding with big-endian format (also known as "network order" and "most significant byte first"). The number of octets for an integer MUST be 1, 2 or 4, depending on usage in the protocol. Such one-octet integers, henceforth called SIGNED-BYTE, are used for the version-number and tag fields. Such two-byte integers, henceforth called SIGNED-SHORT are used for the operation-id, status-code and length fields. Four byte integers, henceforth called SIGNED-INTEGER, are used for value fields and the request-id.
Si j'ai le temps je te donnerai une solution générale, pour les nombres positifs comme négatifs. Sinon, et si personne d'autre ne le fait, tu peux toujours suivre le conseil que je te donnais au début :
1) string -> integer Utilise ta fonction pour les nombres positifs (de 0 à 4294967295), puis soustrais 4294967296 si le résultat est supérieur ou égal à 2147483648.
2) integer -> string Ajoute 4294967296 si le nombre est négatif, puis utilise ta fonction pour les nombres positifs (de 0 à 4294967295).
J'ai fait : if ($initial_value < 0) $int4 = chr($int4) | chr(0x80); else $int4 = chr($int4); $value = $int4.chr($int3).chr($int2).chr($int1);
Mais je ne sais pas si c'est bon (désolé d'être mal-comprenant).
Les fonctions après correction :
// {{{ _integerBuild ($integer) protected function _integerBuild ($value) {
if ($value >= 2147483647 || $value < -2147483648) { trigger_error(_("Values must be between -2147483648 and 2147483647: assuming '0'"),E_USER_WARNING); return chr(0x00).chr(0x00).chr(0x00).chr(0x00); }
À la limite, vu que les entiers positifs entre 2147483648 et 4294967295
sont représentés de façon exacte par les flottants (pourvu que tu sois
sur une machine où les flottants sont sur 64 bits ou plus), tu peux
faire les calculs pour des nombres positifs, et ajouter ou soustraire
4294967296 selon le cas.
C'est indifféremment sur du 32 ou 64bits :-/
##############################################
// {{{ _interpretInteger($value)
protected function _interpretInteger($value) {
// they are _signed_ integers
$negative = false;
$value_parsed = 0;
for ($i = strlen($value) ; $i > 0 ; $i --)
Je n'aime pas beaucoup parcourir les tableaux du plus grand indice au
plus petit, mais bon, c'est ton choix. Vu comment tu fais, tu devras en
plus faire « - 1 » à chaque utilisation de l'indice. Par ailleurs, j'ai
l'impression que ta fonction suppose un ordre de rangement « little
endian », ce qui la rend un peu spécifique au type de machine.
c'est du big endian:
RFC 2910:
Every integer in this encoding MUST be encoded as a signed integer using
two's-complement binary encoding with big-endian format (also known as
"network order" and "most significant byte first"). The number of octets
for an integer MUST be 1, 2 or 4, depending on usage in the protocol.
Such one-octet integers, henceforth called SIGNED-BYTE, are used for the
version-number and tag fields. Such two-byte integers, henceforth called
SIGNED-SHORT are used for the operation-id, status-code and length
fields. Four byte integers, henceforth called SIGNED-INTEGER, are used
for value fields and the request-id.
Si j'ai le temps je te donnerai une solution générale, pour les nombres
positifs comme négatifs. Sinon, et si personne d'autre ne le fait, tu
peux toujours suivre le conseil que je te donnais au début :
1) string -> integer
Utilise ta fonction pour les nombres positifs (de 0 à 4294967295),
puis soustrais 4294967296 si le résultat est supérieur ou égal à
2147483648.
2) integer -> string
Ajoute 4294967296 si le nombre est négatif, puis utilise ta fonction
pour les nombres positifs (de 0 à 4294967295).
J'ai fait :
if ($initial_value < 0)
$int4 = chr($int4) | chr(0x80);
else
$int4 = chr($int4);
$value = $int4.chr($int3).chr($int2).chr($int1);
Mais je ne sais pas si c'est bon (désolé d'être mal-comprenant).
Les fonctions après correction :
// {{{ _integerBuild ($integer)
protected function _integerBuild ($value) {
if ($value >= 2147483647 || $value < -2147483648) {
trigger_error(_("Values must be between -2147483648
and 2147483647: assuming '0'"),E_USER_WARNING);
return chr(0x00).chr(0x00).chr(0x00).chr(0x00);
}
À la limite, vu que les entiers positifs entre 2147483648 et 4294967295 sont représentés de façon exacte par les flottants (pourvu que tu sois sur une machine où les flottants sont sur 64 bits ou plus), tu peux faire les calculs pour des nombres positifs, et ajouter ou soustraire 4294967296 selon le cas.
C'est indifféremment sur du 32 ou 64bits :-/
############################################## // {{{ _interpretInteger($value) protected function _interpretInteger($value) { // they are _signed_ integers $negative = false; $value_parsed = 0;
for ($i = strlen($value) ; $i > 0 ; $i --)
Je n'aime pas beaucoup parcourir les tableaux du plus grand indice au plus petit, mais bon, c'est ton choix. Vu comment tu fais, tu devras en plus faire « - 1 » à chaque utilisation de l'indice. Par ailleurs, j'ai l'impression que ta fonction suppose un ordre de rangement « little endian », ce qui la rend un peu spécifique au type de machine.
c'est du big endian:
RFC 2910:
Every integer in this encoding MUST be encoded as a signed integer using two's-complement binary encoding with big-endian format (also known as "network order" and "most significant byte first"). The number of octets for an integer MUST be 1, 2 or 4, depending on usage in the protocol. Such one-octet integers, henceforth called SIGNED-BYTE, are used for the version-number and tag fields. Such two-byte integers, henceforth called SIGNED-SHORT are used for the operation-id, status-code and length fields. Four byte integers, henceforth called SIGNED-INTEGER, are used for value fields and the request-id.
Si j'ai le temps je te donnerai une solution générale, pour les nombres positifs comme négatifs. Sinon, et si personne d'autre ne le fait, tu peux toujours suivre le conseil que je te donnais au début :
1) string -> integer Utilise ta fonction pour les nombres positifs (de 0 à 4294967295), puis soustrais 4294967296 si le résultat est supérieur ou égal à 2147483648.
2) integer -> string Ajoute 4294967296 si le nombre est négatif, puis utilise ta fonction pour les nombres positifs (de 0 à 4294967295).
J'ai fait : if ($initial_value < 0) $int4 = chr($int4) | chr(0x80); else $int4 = chr($int4); $value = $int4.chr($int3).chr($int2).chr($int1);
Mais je ne sais pas si c'est bon (désolé d'être mal-comprenant).
Les fonctions après correction :
// {{{ _integerBuild ($integer) protected function _integerBuild ($value) {
if ($value >= 2147483647 || $value < -2147483648) { trigger_error(_("Values must be between -2147483648 and 2147483647: assuming '0'"),E_USER_WARNING); return chr(0x00).chr(0x00).chr(0x00).chr(0x00); }
Le 12/01/2006 22:03, Thomas Harding me répondait :
À la limite, vu que les entiers positifs entre 2147483648 et 4294967295 sont représentés de façon exacte par les flottants (pourvu que tu sois sur une machine où les flottants sont sur 64 bits ou plus), tu peux faire les calculs pour des nombres positifs, et ajouter ou soustraire 4294967296 selon le cas.
C'est indifféremment sur du 32 ou 64bits :-/
Bof... des flottants 32 bits en PHP, je ne suis pas sûr qu'il y ait beaucoup d'implémentations qui aient ça. Je soupçonne bien que le minimum soit 32 bits pour les entiers et 64 bits pour les flottants sur les machines 32 bits, 64 bits pour les entiers sur les machines 64 bits. Cela dit, je n'ai pas vérifié.
[...]
J'ai fait : if ($initial_value < 0) $int4 = chr($int4) | chr(0x80); else $int4 = chr($int4); $value = $int4.chr($int3).chr($int2).chr($int1);
Mais je ne sais pas si c'est bon (désolé d'être mal-comprenant).
[ suivi par des modifs de la solution compliquée du début ]
Tu n'as pas lu les articles de Marc et Vincent ? Je ne connaissais pas, mais faire cette opération en natif et en une ou deux lignes, ça me semble préférable à réinventer la roue.
http://fr.php.net/pack http://fr.php.net/unpack
Sinon, si c'est pour le plaisir, le code résultant devrait ressembler à quelque chose comme ça.
(non testé car ça n'en vaut vraiment pas la peine àmha)
-- Olivier Miakinen Troll du plus sage chez les conviviaux : le nouveau venu, avec son clan, s'infiltre dans les groupes de nouvelles. (3 c.)
Le 12/01/2006 22:03, Thomas Harding me répondait :
À la limite, vu que les entiers positifs entre 2147483648 et 4294967295
sont représentés de façon exacte par les flottants (pourvu que tu sois
sur une machine où les flottants sont sur 64 bits ou plus), tu peux
faire les calculs pour des nombres positifs, et ajouter ou soustraire
4294967296 selon le cas.
C'est indifféremment sur du 32 ou 64bits :-/
Bof... des flottants 32 bits en PHP, je ne suis pas sûr qu'il y ait
beaucoup d'implémentations qui aient ça. Je soupçonne bien que le
minimum soit 32 bits pour les entiers et 64 bits pour les flottants
sur les machines 32 bits, 64 bits pour les entiers sur les machines
64 bits. Cela dit, je n'ai pas vérifié.
[...]
J'ai fait :
if ($initial_value < 0)
$int4 = chr($int4) | chr(0x80);
else
$int4 = chr($int4);
$value = $int4.chr($int3).chr($int2).chr($int1);
Mais je ne sais pas si c'est bon (désolé d'être mal-comprenant).
[ suivi par des modifs de la solution compliquée du début ]
Tu n'as pas lu les articles de Marc et Vincent ? Je ne connaissais pas,
mais faire cette opération en natif et en une ou deux lignes, ça me
semble préférable à réinventer la roue.
http://fr.php.net/pack
http://fr.php.net/unpack
Sinon, si c'est pour le plaisir, le code résultant devrait ressembler à
quelque chose comme ça.
Le 12/01/2006 22:03, Thomas Harding me répondait :
À la limite, vu que les entiers positifs entre 2147483648 et 4294967295 sont représentés de façon exacte par les flottants (pourvu que tu sois sur une machine où les flottants sont sur 64 bits ou plus), tu peux faire les calculs pour des nombres positifs, et ajouter ou soustraire 4294967296 selon le cas.
C'est indifféremment sur du 32 ou 64bits :-/
Bof... des flottants 32 bits en PHP, je ne suis pas sûr qu'il y ait beaucoup d'implémentations qui aient ça. Je soupçonne bien que le minimum soit 32 bits pour les entiers et 64 bits pour les flottants sur les machines 32 bits, 64 bits pour les entiers sur les machines 64 bits. Cela dit, je n'ai pas vérifié.
[...]
J'ai fait : if ($initial_value < 0) $int4 = chr($int4) | chr(0x80); else $int4 = chr($int4); $value = $int4.chr($int3).chr($int2).chr($int1);
Mais je ne sais pas si c'est bon (désolé d'être mal-comprenant).
[ suivi par des modifs de la solution compliquée du début ]
Tu n'as pas lu les articles de Marc et Vincent ? Je ne connaissais pas, mais faire cette opération en natif et en une ou deux lignes, ça me semble préférable à réinventer la roue.
http://fr.php.net/pack http://fr.php.net/unpack
Sinon, si c'est pour le plaisir, le code résultant devrait ressembler à quelque chose comme ça.
Remplacer les « + » par des « | » pour diminuer les risques d'ennuis (conversion en float) -- quoique je ne suis pas sûr que ce soit nécessaire.
Bon, mais encore une fois, si c'est pour une utilisation pratique et pas pour prouver que tu es vachement fort en programmation, autant utiliser les fonctions natives.
-- Olivier Miakinen Troll du plus sage chez les conviviaux : le nouveau venu, avec son clan, s'infiltre dans les groupes de nouvelles. (3 c.)
Le 12/01/2006 22:25, je répondais à Thomas Harding :
Sinon, si c'est pour le plaisir, le code résultant devrait ressembler à
quelque chose comme ça.
Remplacer les « + » par des « | » pour diminuer les risques d'ennuis
(conversion en float) -- quoique je ne suis pas sûr que ce soit nécessaire.
Bon, mais encore une fois, si c'est pour une utilisation pratique et pas
pour prouver que tu es vachement fort en programmation, autant utiliser
les fonctions natives.
--
Olivier Miakinen
Troll du plus sage chez les conviviaux : le nouveau venu, avec
son clan, s'infiltre dans les groupes de nouvelles. (3 c.)
Remplacer les « + » par des « | » pour diminuer les risques d'ennuis (conversion en float) -- quoique je ne suis pas sûr que ce soit nécessaire.
Bon, mais encore une fois, si c'est pour une utilisation pratique et pas pour prouver que tu es vachement fort en programmation, autant utiliser les fonctions natives.
-- Olivier Miakinen Troll du plus sage chez les conviviaux : le nouveau venu, avec son clan, s'infiltre dans les groupes de nouvelles. (3 c.)