2016-04-23 3 views
2

Contexte: Je suis en train de lire/écrire des données qui, pour des raisons de stockage, sont des entiers de 24 bits (signés ou non signés, 8 valeurs octales). J'ai besoin de stocker/lire un grand nombre de ces entiers avec pack et unpack. L'application est critique pour l'espace, donc l'utilisation d'entiers 32 bits n'est pas souhaitable.liste de paquets d'entiers 24 bits dans php

Cependant, pack ne semble pas avoir une option pour les entiers 24 bits. Comment fait-on face à cela? J'utilise actuellement une fonction personnalisée

function pack24bit($n) { 
    $b3 = $n%256; 
    $b2 = $n/256; 
    $b1 = $b2/256; 
    $b2 = $b2%256; 
    return pack('CCC',$b1,$b2,$b3); 
} 

et

function unpack24bit($packed) { 
    $arr = unpack('C3b',$packed); 
    return 256*(256*$arr['b1']+$arr['b2'])+$arr['b3']; 
} 

mais peut-être il y a des moyens plus directs?

+1

Pourriez-vous utiliser la chaîne de format "CS" qui vous donnerait 24 bits? – Graeme

+0

soyez conscient que la taille de php int dépend de la plate-forme. Ils pourraient être 32 bits. Ils pourraient également être 64 bits –

+0

@ nl-x Pourriez-vous expliquer comment cette remarque se rapporte à ma question? Je ne pense pas que cela ait de l'importance quand 24 bits sont le maximum avec lequel je travaille. – user1111929

Répondre

2

Il n'existe pas de nombre entier de 24 bits sur une CPU moderne dont je suis conscient, ce qui explique pourquoi l'emballage souhaité n'est pas directement pris en charge.

Je recommande d'emballer vos octets individuellement, comme vous l'avez suggéré. Soyez conscient de l'endianness.

+0

Pourriez-vous préciser ce que vous entendez par «Soyez conscient de l'endianess»? En regardant http://php.net/manual/en/function.pack.php, il semble que 'C' soit ma seule option de drapeau, il n'y a pas de place pour la spécification de l'endianess. – user1111929

+0

@ user1111929: Exactement. Vous devez gérer cela vous-même lorsque vous divisez vos données en octets puis que vous les reliez à l'autre extrémité: à un moment donné, vous devez décider quel sera le code à utiliser pour ces choses. Il devrait suffire de documenter quelle endianness vous avez décidé d'utiliser dans votre représentation d'octets empaquetés. –

+0

Je comprends le pourquoi, mais je ne comprends pas le comment. Comment puis-je 'décider' quelle endianesse utiliser? Il me semble que le système décide automatiquement l'endianess pour moi et ne m'offre pas le choix dans cela. Ce qui aurait en effet un effet désastreux quand un système futur l'interprète dans l'autre sens, mais je ne vois pas comment contrer cela étant donné que je n'ai que le drapeau 'C'. – user1111929