J'ai un tableau de 8 octets et j'essaye de le convertir en C++ long, et je n'arrive pas à le comprendre. D'après ce que je pourrais dire, les nombres longs ne sont que de 4 octets, quelqu'un peut-il fournir des informations à ce sujet? Cela va-t-il importer si c'est 32 ou 64 bits?Convertir un tableau de 8 octets en long signé en C++
Répondre
Certains entiers longs ont 8 octets, d'autres 4. La variante de 8 octets n'existe généralement que sur les systèmes 64 bits. Vérifiez this page si vous voulez avoir une idée.
Bien sûr, nous ne savons pas ce que c'est dans votre cas, donc vous devrez poster plus de détails. Par mesure de sécurité, vous pouvez décider de placer les 8 octets dans 2 entiers longs de toute façon. De cette façon, cela fonctionnera toujours. Dans le pire des cas, vous gaspilleriez la moitié de votre espace de stockage.
La variante de 8 octets ne doit pas exister uniquement sur les systèmes 64 bits. – aib
Vous devriez probablement utiliser un int64_t
dont la longueur est garantie à 8 octets.
Vous n'indiquez pas comment vos données sont représentées (leur endianness) dans votre tableau mais vous pouvez utiliser reinterpret_cast<>
ou mieux: utilisez les opérations de décalage pour "construire" votre nombre entier.
Quelque chose comme:
unsigned char array[8] = { /* Some values here */ };
uint64_t value =
static_cast<uint64_t>(array[0]) |
static_cast<uint64_t>(array[1]) << 8 |
static_cast<uint64_t>(array[2]) << 16 |
static_cast<uint64_t>(array[3]) << 24 |
static_cast<uint64_t>(array[4]) << 32 |
static_cast<uint64_t>(array[5]) << 40 |
static_cast<uint64_t>(array[6]) << 48 |
static_cast<uint64_t>(array[7]) << 56;
Un 'long' est long d'au moins 4 octets. Cela peut être plus. Beaucoup plus. – aib
@aib: J'utilise un 'uin64_t' dans mon exemple, pas un' long'. Pourquoi la downvote? – ereOn
Vous l'avez fait, mais vous avez changé votre réponse. Clever :) – thomaspaulb
Seulement C99 a des types garantis pour contenir 64 bits d'information - long long
et int*64_t
. Pour C++, vous devriez rechercher une classe/bibliothèque BigInt. Ou, comme cela a été suggéré, lancez votre propre classe en utilisant deux long
s.
Une autre méthode de conversion entre les types de données, que je trouve pratique dans certains cas, consiste à utiliser le type de données union, qui vous permet d'accéder à la même partie de la mémoire sous différents types de données. Bien sûr, toutes les autres remarques concernant l'endianness, la taille des types de données, etc.
Par exemple:
union bytes {
unsigned char c[8];
uint64_t l;
} myb;
myb.c[0] = 0;
myb.c[1] = 1;
myb.c[2] = 0;
myb.c[3] = 0;
myb.c[4] = 0;
myb.c[5] = 0;
myb.c[6] = 0;
myb.c[7] = 0;
cout << "value of myb.l: " << myb.l << "\n";
Poster un peu plus sur ce que vous voulez atteindre, peut-être un exemple. –
Voir aussi: http://stackoverflow.com/questions/271076/what-is-the-difference-between-an-int-and-a-long-in-c et http://stackoverflow.com/questions/ 589575/c-size-of-int-long-etc – thomaspaulb
Bien qu'ils ne soient généralement disponibles que pour des valeurs de 16 et 32 bits, vous trouverez peut-être des parallèles avec la famille de fonctions "ntohl". Pour Linux/GCC, ils sont implémentés sur bits/byteswap.h qui a également __bswap_64, bien que ce soit hautement non-standard, il illustre l'utilisation de l'instruction bswap d'Intel, et rorw/rorl pour les processeurs plus anciens. Sur FreeBSD, il y a un en-tête sys/endian.h. –