Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Re: A portable code to create a 4-bytes Big Endian twos complement signed integer in a misaligned address

Reply
Thread Tools

Re: A portable code to create a 4-bytes Big Endian twos complement signed integer in a misaligned address

 
 
Tim Rentsch
Guest
Posts: n/a
 
      03-19-2011
pozz <(E-Mail Removed)> writes:

> I need a variable that can represents numbers between -100000 and
> +100000. int variables could be only 16-bit on some implementations,
> so I use int32_t type:
> int32_t x;
> Is it correct?
>
> Now I need to create a data packet (to send over a network) with the
> following syntax:
> - Byte 1: SOP (Start of Packet)
> - Byte 2-3-4-5: value in Big Endian twos complement
> - Byte 6: EOP (End of Packet)
>
> How can I do that in the most portable way, assuming only the same
> method to store negative numbers in memory (twos complement)?
>
> One solution could be:
> unsigned char data[6] = { SOP, 0, 0, 0, 0, EOP };
> data[1] = (x >> 24) & 0xFF;
> data[2] = (x >> 16) & 0xFF;
> data[3] = (x >> & 0xFF;
> data[4] = (x >> 0) & 0xFF;
> This code should work with Big- or Little-Endian implementations.
>
> Or is it better to use htons()/htonl()?
> int32_t tmp;
> unsigned char data[6] = { SOP, 0, 0, 0, 0, EOP };
> tmp = htonl(x);
> memcpy (&data[1], &tmp, 4);
> Should I use htonl() or htons()? I think on some architecture htons()
> could be sufficient (short int are 32-bits), on others I need htonl
> (short int are 16-bits).
>
> And what can I do if I need a packet with a 3-byte signed integer,
> like the following:
> - Byte 1: SOP (Start of Packet)
> - Byte 2-3-4: value in Big Endian twos complement
> - Byte 5: EOP (End of Packet)


I suggest these (suitably documented, of course):

unsigned char *
store_as_four_octets_high_to_low( void *where, long what ){
unsigned char *result = where;
unsigned long v = what;

result[0] = v>>24 & 0xFF;
result[1] = v>>16 & 0xFF;
result[2] = v>>8 & 0xFF;
result[3] = v>>0 & 0xFF;

return result;
}

Hint: in the three octet version, the assignment statements
need to be revised/condensed.


long
read_as_four_octets_high_to_low( void *where ){
unsigned char *w = where;
unsigned long v;
const unsigned long low = 0x7fffffff, high = low + 1;

v = w[0]&0xFF;
v = v<<8 | w[1]&0xFF;
v = v<<8 | w[2]&0xFF;
v = v<<8 | w[3]&0xFF;

return (long)(v & low) - (long)(v/2 & high/2) - (long)(v/2 & high/2);
}

Hint: in the three octet version, there should be one less
assignment statement, and the initializer for 'low' needs
a different value.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: A portable code to create a 4-bytes Big Endian twos complementsigned integer in a misaligned address Jorgen Grahn C Programming 2 03-25-2011 12:43 PM
Re: A portable code to create a 4-bytes Big Endian twos complementsigned integer in a misaligned address James Kuyper C Programming 3 03-19-2011 02:19 PM
Re: A portable code to create a 4-bytes Big Endian twos complement Spiros Bousbouras C Programming 6 03-18-2011 03:14 PM
little endian , big endian , big headache manishster@gmail.com C Programming 5 08-31-2006 12:28 AM
twos complement data redstripe VHDL 3 04-24-2006 01:35 PM



Advertisments