|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
[C] Invertire ordine dei byte di un dobule
Ciao a tutti!
Devo inserire in un sorgente una direttiva che a seconda se la macchina sul quale vado a eseguire la macchina è Little Endian o Big Endian, mi inverta l'ordine dei byte di un double. Devo scrivere una cosa del genere: Codice:
#include<endian.h> ... #if __BYTE_ORDER==__LITTLE_ENDIAN ... #endif #if __BYTE_ORDER==__BIG_ENDIAN ... #endif |
|
|
|
|
|
#2 | |
|
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
Non so se mi sono spiegato ... se qualcuno mi da un file binario e mi dice che dentro c'è un double in BE, se la mia macchina è già in BE, non devo fare niente, altrimenti lo devo invertire. Volevo capire cioè esattamente cosa devi fare.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
|
|
|
|
|
#3 |
|
Member
Iscritto dal: Oct 2004
Città: Bologna
Messaggi: 50
|
Sapendo che su internet i byte più significativi vengono prima, potresti utilizzare le funzioni ntohl e htonl.
Ti copioincollo la man page: Codice:
NAME
htonl, htons, ntohl, ntohs - convert values between host and network
byte order
SYNOPSIS
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
DESCRIPTION
The htonl() function converts the unsigned integer hostlong from host
byte order to network byte order.
The htons() function converts the unsigned short integer hostshort from
host byte order to network byte order.
The ntohl() function converts the unsigned integer netlong from network
byte order to host byte order.
The ntohs() function converts the unsigned short integer netshort from
network byte order to host byte order.
On the i80x86 the host byte order is Least Significant Byte first,
whereas the network byte order, as used on the Internet, is Most Sig-
nificant Byte first.
CONFORMING TO
SUSv3.
Some systems require the inclusion of <netinet/in.h> instead of
<arpa/inet.h>.
SEE ALSO
gethostbyname(3), getservent(3)
__________________
And the salad is frightful! I have an important message to deliver to all the cute people all over the world. If you're out there and you're cute, maybe you're beautiful. I just want to tell you something: there's more of us ugly mother-fuckers than you are, hey-y, so watch out. |
|
|
|
|
|
#4 | |
|
Member
Iscritto dal: Oct 2004
Città: Bologna
Messaggi: 50
|
Quote:
__________________
And the salad is frightful! I have an important message to deliver to all the cute people all over the world. If you're out there and you're cute, maybe you're beautiful. I just want to tell you something: there's more of us ugly mother-fuckers than you are, hey-y, so watch out. |
|
|
|
|
|
|
#5 | |
|
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
Infatti quelle funzioni non posso usarle. Cmq mi serve perché dovrò leggere/scrivere double da/su file binari. Mentre per quanto riguarda gli interi e gli short questa procedura c'è (infatti sono quelle funzioni di cui mi avete parlato poco fa), per i double devo implementarla io. Devo, a prescindere, invertire l'endianness del double perché questo programma non si sa a priori dove verrà eseguito.
|
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Ci ho pensato un pochino. Si può fare così:
Codice:
#include <endian.h>
void swap_endian_double (double *pd)
{
char *p = (char*) pd;
char t;
t = p[0]; p[0] = p[7]; p[7] = t;
t = p[1]; p[1] = p[6]; p[6] = t;
t = p[2]; p[2] = p[5]; p[5] = t;
t = p[3]; p[3] = p[4]; p[4] = t;
}
void adjust_double_be (double *pd)
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
swap_endian_double (pd);
#endif
}
void adjust_double_le (double *pd)
{
#if __BYTE_ORDER == __BIG_ENDIAN
swap_endian_double (pd);
#endif
}
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) Ultima modifica di andbin : 31-05-2006 alle 14:17. |
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
Grazie mille andbin. Vedendo il codice pensavo fosse molto più difficile (non che non lo sia questo). Quindi quando io dovrò scrivere su file binario swap_double() oppure devo richiamare adjust_double_from_le() (nel caso in cui sono in un'architettura le)?
|
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
Mi sorge un altro dubbio, ma un char non è più "piccolo" di un double? Cioè facendo quel cast a puntatore a char in teoria si perderebbero informazioni su quel numero, o sbaglio?
|
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
|
Ciao io son nuovo (anche se seguo passivamente da tempo ...)
io ho fatto cosi: Codice:
/*------------------------------*\
DEFINISCI LA MACRO CHE "SWAPPA"
LA TROVI ANCHE SU byteswap.h
\*------------------------------*/
#define swap_64(n) ( \
(((n) & 0xff00000000000000ull) >> 56) \
| (((n) & 0x00ff000000000000ull) >> 40) \
| (((n) & 0x0000ff0000000000ull) >> 24) \
| (((n) & 0x000000ff00000000ull) >> 8 ) \
| (((n) & 0x00000000ff000000ull) << 8 ) \
| (((n) & 0x0000000000ff0000ull) << 24) \
| (((n) & 0x000000000000ff00ull) << 40) \
| (((n) & 0x00000000000000ffull) << 56) )
/*-------------------------*\
FUNZIONE CHE "SWAPPA"
\*-------------------------*/
double Swap_64( double d )
{
long long ll;
memcpy( &ll, &d, sizeof(long long) );
ll = swap_64(ll);
memcpy( &d, &ll, sizeof(long long) );
return d;
}
e poi lo riconverti in double l'ho anche testato con un mini prog in C e funzica Codice:
/*--------*\
\*--------*/
int main()
{
double d = 123.45;
int i;
char c[8];
printf( "d: <%f>\n", d );
d = Swap_64(d);
printf( "d: <%f>\n", d );
memcpy( c, &d, sizeof(long long) );
for ( i = 0; i < 8; i++ )
printf( "%X", c[i] );
puts("");
d = Swap_64(d);
printf( "d: <%f>\n", d );
memcpy( c, &d, sizeof(long long) );
for ( i = 0; i < 8; i++ )
printf( "%X", c[i] );
puts("");
return 0;
}
|
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
Scusa ma long long in ANSI C esiste? E cmq io devo fare uno swap sia se sono in BE che in LE. Quando scrivo su file binario un double, prima modifico la variabile che conterrò temporaneamente quel double e poi la converto tramite la tua swap prima di scriverla su file?
|
|
|
|
|
|
#12 | |
|
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
Quando dovrai scrivere su file, dovrai usare la adjust_double_XX e non la swap_endian_double. Esempio: Codice:
double d = ....; double d_tmp; .... d_tmp = d; adjust_double_be (&d_tmp); fwrite (&d_tmp, 1, sizeof (d_tmp), f);
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
Ho capito grazie. Speriamo che funzioni.
|
|
|
|
|
|
#14 | |
|
Senior Member
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
|
Quote:
'azz! ANSI il long long ??? sai che non lo so pero' ho lavorato su molto SO unix e l'ho sempre trovato. indago ... |
|
|
|
|
|
|
#15 | |
|
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
Nota che io non opero mai sul valore del double direttamente, cioè non faccio alcun cast sul valore del double. Mi viene passato un puntatore a double e lo faccio diventare semplicemente un puntatore a char. Quindi non si perde nulla.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
|
|
|
|
|
#16 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
Perfetto, grazie ancora andbin.
|
|
|
|
|
|
#17 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
Un'altra cosa. Questa procedura va bene anche quando devo leggere il double? Cioè a me serve che mi faccia la conversione da host byte order a network byte order e viceversa.
|
|
|
|
|
|
#18 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
up
|
|
|
|
|
|
#19 | |
|
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
|
|
|
|
|
#20 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
D'accordo ma quando vado a leggere il double da file, devo richiamare questa funzione oppure no?
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 21:51.



















