Newsgroup: it.comp.lang.c
Titolo: Divisione di variabili

Salve a tutti! Mi fareste un esempio su come č possibile separare il
contenuto di una variabile long in due int (nel primo int l'high order word
e nel secondo la low order word)?
Grazie in anticipo!
Giuseppe

Una variabile long che io sappia (almeno in sistemi win x86) č 8 byte.
E un int č 4 byte.
Io te lo potrei dire bit a bit, ma credo che qualcun altro ti possa indicare
una maniera piů efficente per farlo.
Ciao
Claudio

 e nel secondo la low order word)?
La separazione  e` banale. Non e`  pero` possibile sapere quale  dei due
interi conterra` i bit bassi e quale i  bit alti, visto che nel C non e`
presente alcun concetto di endianess.
Per lo split:
unsigned long num;
unsigned int a, b;
int shift = (sizeof(num) / 2) * CHAR_BIT;
a = num >> shift;
b = (num << shift) >> shist;
Gli operatori << e >> sono operatori di shift, che spostano sinistra o a
destra di tot  bit la rappresentazione binaria del numero  a cui vengono
applicati. Le posizioni liberate vengono  riempite di zeri [1]. L'intero
shift (usato  per chiarezza) indica il  numero di spostamenti da  fare e
corrisponde alla meta`  dei bit di un long (CHAR_BIT  mi dice quanti bit
ci sono in un byte, sizeof quanti byte ci sono in un long).
Supponendo di  lavorare su x86  (che e`  little endian), il  primo shift
sposta la word alta su quella bassa  ed assegna il numero ricavato ad a.
Il secondo shift prima sposta la word bassa su quella alta (azzerando di
fatto quella alta), poi rimette la work alta su quella bassa.
Esempio in esadecimale:
num = 0xffffabcd;
(num >> shift) -> 0x0000ffff
(num << shift) -> 0xabcd0000
(num << shift) >> shift -> 0x000abcd
[1] Ho  usato intenzionalmente  di operare  su unsigned  long. Usare gli
operatori di  shift porta ad  un comportamento non definito. Per  i tipi
signed il  bit di segno  potrebbe essere  trattato come tutti  gli altri
bits (e quindi shiftato) oppure potrebbe rimanere al suo posto.
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
Il piu` bel momento dell'amore e` quando ci si illude che duri
per sempre; il piu` brutto, quando ci si accorge che dura
da troppo.

 fatto quella alta), poi rimette la work alta su quella bassa.
Piccola correzione. Non  e` garantito  che un int  sia allineato  ad una
work, ne` che  un long sia allineato ad una  dword. Le dichiarazioni dei
tipi dovrebbero essere modificate cosi`:
#include <stdint.h>
uint64_t num;
uint32_t a, b;
Se il tuo compilatore non supporta il C99 puoi cavartela in questo modo:
#include <limits.h>
#ifndef ULLONG_MAX
#define ULLONG_MAX 0
#endif
#if UINT_MAX == 0xffffffffffffffff
typedef unsigned int DWORD;
#elif ULONG_MAX == 0xffffffffffffffff
typedef unsigned long DWORD;
#elif ULLONG_MAX == 0xffffffffffffffff
typedef unsigned long long DWORD;
#else
#error Impossibile trovare un tipo di dato adatto
#endif
#if USHRT_MAX == 0xffffffff
typedef unsigned short WORD;
#elif UINT_MAX == 0xffffffff
typedef unsigned int WORD;
#elif ULONG_MAX == 0xffffffff
typedef unsigned long WORD;
#elif ULLONG_MAX == 0xffffffff
typedef unsigned long long WORD;
#else
#error Impossibile trovare un tipo di dato adatto
#endif
In questo  modo WORD  e DWORD  saranno dei  typedef per  i tipi  di dato
corretti. 
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
"L'ottimista pensa che questo sia il migliore dei mondi possibili. 
 Il pessimista sa che e` vero" -- J. Robert Oppenheimer

 operatori di  shift porta ad  un comportamento non definito. 
Traduzione:
Ho usato intenzionalmente un unsigned long. Usare gli operatori di shift
su tipi di dato signed porta ad un comportamento non definito.
ciao
un Kronos mi sono mangiato un po' di parole...
-- 
Home: 
http://kronoz.cjb.net
I went to God just to see
And I was looking at me
Saw heaven and hell were lies
When I'm God everyone dies