DSPRelated.com
Forums

bytes[] to int and vice versa

Started by Unknown March 17, 2009
Hi there,

How do I correctly convert an integer to 4 bytes, and how do I
reconstruct the integer from the bytes using C or C++?

I used the following code:


//Converting from int to 4 bytes

int Number;
char buffer[4];


int cc;
for ( cc = 0; cc < 4; cc++)
{
	buffer[cc] =  Number & 0xFF;
	Number >>= 8;
}


//Converting from 4 bytes to int
Number = buffer[3];

int cc;
for ( cc = 1; cc <= 4; cc++)
{
      Number <<= 8;
      Number = Number | buffer[3 - cc];
 }

Will this work?  Do I need to perform type-casting somewhere?

Your times, help and suggestions will be greatly appreciated
Jaco
On Mar 17, 8:41&#4294967295;am, jaco.versf...@gmail.com wrote:
> Hi there, > > How do I correctly convert an integer to 4 bytes, and how do I > reconstruct the integer from the bytes using C or C++? > > I used the following code: > > //Converting from int to 4 bytes > > int Number; > char buffer[4]; > > int cc; > for ( cc = 0; cc < 4; cc++) > { > &#4294967295; &#4294967295; &#4294967295; &#4294967295; buffer[cc] = &#4294967295;Number & 0xFF; > &#4294967295; &#4294967295; &#4294967295; &#4294967295; Number >>= 8; > > } > > //Converting from 4 bytes to int > Number = buffer[3]; > > int cc; > for ( cc = 1; cc <= 4; cc++) > { > &#4294967295; &#4294967295; &#4294967295; Number <<= 8; > &#4294967295; &#4294967295; &#4294967295; Number = Number | buffer[3 - cc]; > &#4294967295;} > > Will this work? &#4294967295;Do I need to perform type-casting somewhere? > > Your times, help and suggestions will be greatly appreciated > Jaco
Your method relies upon the endianness of the system you're running on (it's assuming a little-endian representation). There are times where you do explicitly need to take endianness into account, like when you're trying to implement some defined interface for a file or communication protocol. However, in the case where you just need to fill a byte buffer with the contents of an int, you can just do: #include <string.h> int n = 0x12345678; char n_bytes[sizeof(int)]; memcpy(n_bytes, &n, sizeof(int)); Not really a DSP question; you might try comp.lang.c next time. Jason
On 17 Mar, 13:41, jaco.versf...@gmail.com wrote:
> Hi there, > > How do I correctly convert an integer to 4 bytes, and how do I > reconstruct the integer from the bytes using C or C++?
This is one of the few places where there is a significant difference between C99 and C++. In C99 there are size-specific data types as part of the standard, which allows you to type- cast to char8, int16 etc. There are presently no such size- specific data types as part of the C++ standard. So the int data type you use is specified to be _at_least_ 16 bits (but can be more). To be safe, use long int, which is specifed to be _at_least_ 32 bits (but can be more). Unless you use the C99 size-specific data types, there will always be implementation- and system-specific dependencies in these details. Apart from that, it seems your algorithm is more or less what I would do for these types of conversions. Rune
On 17 Mrz., 13:41, jaco.versf...@gmail.com wrote:
> How do I correctly convert an integer to 4 bytes, and how do I > reconstruct the integer from the bytes using C or C++?
It might be off-topic here. [...]
> int Number; > char buffer[4];
replace "char" with "unsigned char" Also, are you sure that sizeof(char)*4=sizeof(int) ? Consider using int32_t from the header <stdint.h> IIRC these types -- if existent -- are guaranteed to use two's complement for representing signed numbers (unlike int, short, long, ...)
> int cc; > for ( cc = 0; cc < 4; cc++) > { > &#4294967295; &#4294967295; &#4294967295; &#4294967295; buffer[cc] = &#4294967295;Number & 0xFF; > &#4294967295; &#4294967295; &#4294967295; &#4294967295; Number >>= 8; > }
It technically invokes undefined (or imeplemtation-defined?) behaviour because a "plain char" MAY be signed and the rvalue on the right side may not fit into an object of type char. This is why you should use an unsigned char. There's this rule: If you convert some (possibly signed) integer 'a' to an unsigned integer 'b' then a=b mod 2^N where N is the number of bits used in b. This applies for all type combinations as long as the type of b is an unsigned type. If the type of b is signed then all bets are off. Though, usually the bit pattern will be just reinterpreted which makes the rule valid for signed numbers in two's complement as well. But this is not 100% portable. Your compiler vendor should document this behaviour. Cheers! SG
cincydsp@gmail.com wrote:
> On Mar 17, 8:41 am, jaco.versf...@gmail.com wrote: >> Hi there, >> >> How do I correctly convert an integer to 4 bytes, and how do I >> reconstruct the integer from the bytes using C or C++? >>
You can use a C union: typedef union { int lsamp; /* make unsigned if you need it */ unsigned char bytes[4]; } u_i32; A union has the size of the largest element. You can use this to access the bytes of a float too (similarly, use bytes[8] to match a 64bit type). All the comments about endianness apply. Richard Dobson
On 17 Mrz., 14:46, Richard Dobson <richarddob...@blueyonder.co.uk>
wrote:
> You can use a C union: > > typedef union { > &#4294967295; &#4294967295;int lsamp; /* make unsigned if you need it */ > &#4294967295; &#4294967295;unsigned char bytes[4]; > > } u_i32; > > A union has the size of the largest element. > > You can use this to access the bytes of a float too (similarly, use > bytes[8] to match a 64bit &#4294967295;type). All the comments about endianness apply.
You can certainly try and GCC guarantees that it'll work but as far as the ISO C or ISO C++ standard is concerned this invokes undefined behaviour and is therefore not portable. What you CAN do without invokung undefined behaviour is accessing the int through a pointer to unsigned char. This is allowed. Also, you can use memcpy to copy raw bytes. Such a call to memcpy is usually inlined and optimized. The results will be implementation-defined (as for endianess and number of bits in a character etc) Cheers! SG

jaco.versfeld@gmail.com wrote:

> Hi there, > > How do I correctly convert an integer to 4 bytes, and how do I > reconstruct the integer from the bytes using C or C++? > > I used the following code: >
> for ( cc = 0; cc < 4; cc++) > { > buffer[cc] = Number & 0xFF; > Number >>= 8; > }
This is the right way to do that. It works regardless of endianess and the sizes of integers and chars. Lazy ways like using unions or casting pointers are not portable and depend on alignment as well. Vladimir Vassilevsky DSP and Mixed Signal Design Consultant http://www.abvolt.com
On 17 Mrz., 15:15, Vladimir Vassilevsky <antispam_bo...@hotmail.com>
wrote:
> jaco.versf...@gmail.com wrote: > > for ( cc = 0; cc < 4; cc++) > > { > > buffer[cc] = Number & 0xFF; > > Number >>= 8; > > } > > This is the right way to do that. It works regardless of endianess and > the sizes of integers and chars.
...for your definition of "right". According to 6.2.5 (Types) and 6.3.1.3 (Signed and unsigned integers) of the current draft of the C0x standard (which should be unchanged from ISO C90) this also isn't portable because "char" is not guaranteed to be unsigned and a conversion of a value X to a signed integer of type T is implementation-defined if X is not representable in T. 6.3.1.3/3: "Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised." http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1336.pdf Cheers! SG
On Tue, 17 Mar 2009 06:03:39 -0700 (PDT), cincydsp@gmail.com wrote in
comp.dsp:

> On Mar 17, 8:41&#4294967295;am, jaco.versf...@gmail.com wrote: > > Hi there, > > > > How do I correctly convert an integer to 4 bytes, and how do I > > reconstruct the integer from the bytes using C or C++? > > > > I used the following code: > > > > //Converting from int to 4 bytes > > > > int Number; > > char buffer[4]; > > > > int cc; > > for ( cc = 0; cc < 4; cc++) > > { > > &#4294967295; &#4294967295; &#4294967295; &#4294967295; buffer[cc] = &#4294967295;Number & 0xFF;
In the first iteration of this loop, Number and 0xFF will absolutely, positively produce the lowest 8 bits of Number. Regardless of whether it is bit or little endian.
> > &#4294967295; &#4294967295; &#4294967295; &#4294967295; Number >>= 8; > > > > } > > > > //Converting from 4 bytes to int > > Number = buffer[3]; > > > > int cc; > > for ( cc = 1; cc <= 4; cc++) > > { > > &#4294967295; &#4294967295; &#4294967295; Number <<= 8; > > &#4294967295; &#4294967295; &#4294967295; Number = Number | buffer[3 - cc]; > > &#4294967295;} > > > > Will this work? &#4294967295;Do I need to perform type-casting somewhere? > > > > Your times, help and suggestions will be greatly appreciated > > Jaco > > Your method relies upon the endianness of the system you're running on > (it's assuming a little-endian representation). There are times where > you do explicitly need to take endianness into account, like when > you're trying to implement some defined interface for a file or > communication protocol. However, in the case where you just need to > fill a byte buffer with the contents of an int, you can just do:
There is absolutely no dependence on the endianness of the processor for either shifting or masking with & in C. These operations are defined in terms of value, not endianness of operation.
> #include <string.h> > int n = 0x12345678; > char n_bytes[sizeof(int)]; > memcpy(n_bytes, &n, sizeof(int)); > > Not really a DSP question; you might try comp.lang.c next time.
-- Jack Klein Home: http://JK-Technology.Com FAQs for comp.lang.c http://c-faq.com/ comp.lang.c++ http://www.parashift.com/c++-faq-lite/ alt.comp.lang.learn.c-c++ http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
On Tue, 17 Mar 2009 05:41:04 -0700 (PDT), jaco.versfeld@gmail.com
wrote in comp.dsp:

> Hi there, > > How do I correctly convert an integer to 4 bytes, and how do I > reconstruct the integer from the bytes using C or C++? > > I used the following code: > > > //Converting from int to 4 bytes > > int Number; > char buffer[4];
As others have said, better to use unsigned char and unsigned int, even better to use <stdint.h> types. And are you sure that there are four chars in an int? On TI 28xx DSPs, both int and char have 16 bits. On some AD Sharc DSPs, both int and char have 32 bits. In both these cases, one int requires only one char, preferably unsigned, to fit in. -- Jack Klein Home: http://JK-Technology.Com FAQs for comp.lang.c http://c-faq.com/ comp.lang.c++ http://www.parashift.com/c++-faq-lite/ alt.comp.lang.learn.c-c++ http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html