471,076 Members | 1,153 Online

# Question converting unsigned char [] to int

Hi all:

I have an unsigned char array (size 4):

unsigned char array[4];

array[0] = 0x00;
array[1] = 0x00;
array[2] = 0x02;
array[3] = 0xe7;

I would like to convert array[] to an integer.

0x00 0x00 0x02 0xe7 = 00000000 00000000 00000010 11100111 = 743

Any help is appreciated.

Nov 14 '05 #1
18 25760
hi
first u need to understand the relationship between BCD representation.
like 3 is represented as 0111 and not 111. 4 will be considered as 0100
and not 100.so if u r given a number , say 0xe7, which means
11100111,shift it to right by 4.

int temp = array[3] >> 4;
which means
temp = 00001110 (= 0x0e)
int temp2 = array[3] << 4;
temp2 = 01110000 (0x70)
similarly u can split up all the elements by shifting and get the 4 bit
equivalents. convert them to get the exact BCD no.
hope that was of some help.

Nov 14 '05 #2
> I have an unsigned char array (size 4):

unsigned char array[4];

array[0] = 0x00;
array[1] = 0x00;
array[2] = 0x02;
array[3] = 0xe7;

I would like to convert array[] to an integer.

0x00 0x00 0x02 0xe7 = 00000000 00000000 00000010 11100111 = 743

Any help is appreciated.

C doesn't guarantee that UCHAR_MAX <= UINT_MAX nor does it guarantee
that UINT_MAX is >= 0xFFFFFFFF. But here is something that will work if
you can guarantee the values in the array are <= 0xFF:

#define lengthof(a) (sizeof(a)/sizeof(a[0]))

const unsigned char array[4] = { 0, 0, 0x02, 0xe7 };
unsigned long ui = 0;
unsigned long mult = 1;

/*
it looks like you wanted big endian conversion. For little
endian, just index the array in the regular order
*/
for (unsigned i = 0; i < 4; ++i) {
ui += mult * array[lengthof(array)-1-i];
mult <<= 8;
}

assert(ui == 743);

Otherwise replace unsigned long and unsigned char with the uint32_t and
uint8_t types in stdint.h which is probably what you intended anyway.

Nov 14 '05 #3

Me wrote:
I have an unsigned char array (size 4):

unsigned char array[4];

array[0] = 0x00;
array[1] = 0x00;
array[2] = 0x02;
array[3] = 0xe7;

I would like to convert array[] to an integer.

0x00 0x00 0x02 0xe7 = 00000000 00000000 00000010 11100111 = 743

Any help is appreciated.

C doesn't guarantee that UCHAR_MAX <= UINT_MAX nor does it guarantee
that UINT_MAX is >= 0xFFFFFFFF. But here is something that will work if
you can guarantee the values in the array are <= 0xFF:

#define lengthof(a) (sizeof(a)/sizeof(a[0]))

const unsigned char array[4] = { 0, 0, 0x02, 0xe7 };
unsigned long ui = 0;
unsigned long mult = 1;

/*
it looks like you wanted big endian conversion. For little
endian, just index the array in the regular order
*/

<snip>

You don't need to do that for little endian. Whether it is little
or big endian, array[0] will always be 0,
array[1] will always be 0,
array[2] will always be 0x02, and
array[3] will always be 0xe7.

Nov 14 '05 #4
No Such Luck wrote:
Hi all:

I have an unsigned char array (size 4):

unsigned char array[4];

array[0] = 0x00;
array[1] = 0x00;
array[2] = 0x02;
array[3] = 0xe7;

I would like to convert array[] to an integer.

0x00 0x00 0x02 0xe7 = 00000000 00000000 00000010 11100111 = 743

#include <stdio.h>
#include <limits.h>

int main(void)
{
unsigned i;
unsigned char a[4] = { 0x00, 0x00, 0x02, 0xe7 };

i = a[3] | (a[2] | (a[1] | a[0] << CHAR_BIT) << CHAR_BIT) <<
CHAR_BIT;
printf("i built up with left shifts & ors: %u\n", i);
return 0;
}

i built up with left shifts & ors: 743
Nov 14 '05 #5
Me wrote:
C doesn't guarantee that UCHAR_MAX <= UINT_MAX...

Yes, it does. [cf 6.2.5p8]

--
Peter

Nov 14 '05 #6
> > C doesn't guarantee that UCHAR_MAX <= UINT_MAX...

Yes, it does. [cf 6.2.5p8]

Yeah, that was really stupid of me. I meant to say that C doesn't
guarantee that pow(UCHAR_MAX+1,4)-1 <= UINT_MAX.

Nov 14 '05 #7
ya*******@gmail.com wrote:

[ If you _must_ use Google Broken Beta to post to Usenet, could you
on how to do so abound on Usenet, including in someone's sig here. ]
first u need to understand the relationship between BCD representation.
BCD is irrelevant to the OP's problem; he's trying to concatenate bytes
into a (normal binary) integer, nothing more complicated.
like 3 is represented as 0111 and not 111.

Where'd you get that? Even in BCD, 3 is represented by 0011, and 0111 is
7. That alone should've tipped you off that BCD is not the issue.

BTW, if you want to be taken seriously as a professional, learn to write
without script-kiddyisms such as "u" for you.

Richard
Nov 14 '05 #8
Martin Ambuhl wrote:

No Such Luck wrote:
Hi all:

I have an unsigned char array (size 4):

unsigned char array[4];

array[0] = 0x00;
array[1] = 0x00;
array[2] = 0x02;
array[3] = 0xe7;

I would like to convert array[] to an integer.

0x00 0x00 0x02 0xe7 = 00000000 00000000 00000010 11100111 = 743

#include <stdio.h>
#include <limits.h>

int main(void)
{
unsigned i;
unsigned char a[4] = { 0x00, 0x00, 0x02, 0xe7 };

i = a[3] | (a[2] | (a[1] | a[0] << CHAR_BIT) << CHAR_BIT) <<
CHAR_BIT;
printf("i built up with left shifts & ors: %u\n", i);
return 0;
}

i built up with left shifts & ors: 743

If you're trying to make 743,
then it should be 8 instead of CHAR_BIT.

--
pete
Nov 14 '05 #9
On Thu, 16 Jun 2005 21:30:13 -0700, Me wrote:
I have an unsigned char array (size 4):

unsigned char array[4];

array[0] = 0x00;
array[1] = 0x00;
array[2] = 0x02;
array[3] = 0xe7;

I would like to convert array[] to an integer.

0x00 0x00 0x02 0xe7 = 00000000 00000000 00000010 11100111 = 743

Any help is appreciated.
C doesn't guarantee that UCHAR_MAX <= UINT_MAX nor does it guarantee

It does but that has been covered in other replies.
that UINT_MAX is >= 0xFFFFFFFF. But here is something that will work if
you can guarantee the values in the array are <= 0xFF:
Right.
#define lengthof(a) (sizeof(a)/sizeof(a[0]))

const unsigned char array[4] = { 0, 0, 0x02, 0xe7 };
unsigned long ui = 0;
unsigned long mult = 1;

/*
it looks like you wanted big endian conversion. For little
endian, just index the array in the regular order
*/
for (unsigned i = 0; i < 4; ++i) {
ui += mult * array[lengthof(array)-1-i];
mult <<= 8;
}
Or perhaps

for (unsigned i = 0; i < lengthof(array); i++)
ui = (ui << 8) | array[i];
assert(ui == 743);

Otherwise replace unsigned long and unsigned char with the uint32_t and
uint8_t types in stdint.h which is probably what you intended anyway.

You're much better off using unsigned long and unsigned char. They do the
job portably whereas uint32_t and uint8_t are non-=portable because an
implementation is only required to support them if it has a type with the
appropriate representation available. And of course they aren't supported
in C90 at all.

Lawrence

Nov 14 '05 #10
pete wrote:
Martin Ambuhl wrote:
No Such Luck wrote:
Hi all:

I have an unsigned char array (size 4):

unsigned char array[4];

array[0] = 0x00;
array[1] = 0x00;
array[2] = 0x02;
array[3] = 0xe7;

I would like to convert array[] to an integer.

0x00 0x00 0x02 0xe7 = 00000000 00000000 00000010 11100111 = 743

#include <stdio.h>
#include <limits.h>

int main(void)
{
unsigned i;
unsigned char a[4] = { 0x00, 0x00, 0x02, 0xe7 };

i = a[3] | (a[2] | (a[1] | a[0] << CHAR_BIT) << CHAR_BIT) <<
CHAR_BIT;
printf("i built up with left shifts & ors: %u\n", i);
return 0;
}

i built up with left shifts & ors: 743

If you're trying to make 743,
then it should be 8 instead of CHAR_BIT.

But if you are trying to use whatever values an unsigned char holds,
it's CHAR_BIT. I never trust poster's arithmetic. It is "I would like
to conver array[] to an integer" to which I was responding, not the "=
743". The fact is, that "if you're trying to make 743" both 8 and
CHAR_BIT are irrelevant: just f*ing output 743 and screw where it came from.
Nov 14 '05 #11
No Such Luck wrote:
Hi all:

I have an unsigned char array (size 4):

unsigned char array[4];

array[0] = 0x00;
array[1] = 0x00;
array[2] = 0x02;
array[3] = 0xe7;

I would like to convert array[] to an integer.

0x00 0x00 0x02 0xe7 = 00000000 00000000 00000010 11100111 = 743

#include <stdio.h>
#include <limits.h>

int main(void)
{
unsigned i;
unsigned char a[4] = { 0x00, 0x00, 0x02, 0xe7 };

i = a[3] | (a[2] | (a[1] | a[0] << CHAR_BIT) << CHAR_BIT) <<
CHAR_BIT;
printf("i built up with left shifts & ors: %u\n", i);
return 0;
}

i built up with left shifts & ors: 743

Although the code shown may work for this example, on different
values of the array elements it might result in undefined
behavior. The unsigned character values normally promote to
(signed) int, and shifting a signed value can produce UB.
Nov 14 '05 #12
Tim Rentsch wrote:
No Such Luck wrote:

unsigned char array[4];

array[0] = 0x00;
array[1] = 0x00;
array[2] = 0x02;
array[3] = 0xe7;

I would like to convert array[] to an integer.
0x00 0x00 0x02 0xe7 = 00000000 00000000 00000010 11100111 = 743
unsigned i;
unsigned char a[4] = { 0x00, 0x00, 0x02, 0xe7 };

i = a[3] | (a[2] | (a[1] | a[0] << CHAR_BIT) << CHAR_BIT) <<
CHAR_BIT;

Although the code shown may work for this example, on different
values of the array elements it might result in undefined
behavior. The unsigned character values normally promote to
(signed) int, and shifting a signed value can produce UB.

If E1 is a signed int, then E1 << E2 only produces UB if E1
is negative or if E1 x 2^E2 is not representable by a signed int.

This situation would only arise if a[0] is 0x80 or greater
(assuming INT_MAX is 0x7FFFFFFF).
Martin Ambuhl's suggestion can be fixed by inserting a cast to
unsigned just after the first '|'.

Another option would be to replace "<< CHAR_BIT" with "* 256UL"
(the OP appears to want this, even if chars are not 8-bit).

Nov 14 '05 #13
"Old Wolf" <ol*****@inspire.net.nz> writes:
Tim Rentsch wrote:
No Such Luck wrote:

unsigned char array[4];

array[0] = 0x00;
array[1] = 0x00;
array[2] = 0x02;
array[3] = 0xe7;

I would like to convert array[] to an integer.
0x00 0x00 0x02 0xe7 = 00000000 00000000 00000010 11100111 = 743

unsigned i;
unsigned char a[4] = { 0x00, 0x00, 0x02, 0xe7 };

i = a[3] | (a[2] | (a[1] | a[0] << CHAR_BIT) << CHAR_BIT) <<
CHAR_BIT;
Although the code shown may work for this example, on different
values of the array elements it might result in undefined
behavior. The unsigned character values normally promote to
(signed) int, and shifting a signed value can produce UB.

If E1 is a signed int, then E1 << E2 only produces UB if E1
is negative or if E1 x 2^E2 is not representable by a signed int.

This situation would only arise if a[0] is 0x80 or greater
(assuming INT_MAX is 0x7FFFFFFF).

Yes, it produces undefined behavior only in some circumstances.
That's what I said.

Martin Ambuhl's suggestion can be fixed by inserting a cast to
unsigned just after the first '|'.

Yes, doing that will remove undefined behavior on some systems.

It's better though to write code that won't have undefined behavior
even on systems where INT_MAX < 0x7FFFFFFF; the code Lawrence Kirby
gave, for example.
Nov 14 '05 #14
Groovy hepcat ya*******@gmail.com was jivin' on 16 Jun 2005 21:20:41
-0700 in comp.lang.c.
Re: Question converting unsigned char [] to int's a cool scene! Dig
it!
hi
Please provide context by quoting (the relevant portions of) the
post to which you are following up. Also, do not use d00dspeak-isms
think clearly before answering questions, so as not to post some utter
nonsense or red herring.
first u need to understand the relationship between BCD representation.
Nonsense! What does BCD have to do with the price of fish? The OP
didn't mention BCD. He asked how to convert an array of unsigned char
to an integer.
like 3 is represented as 0111 and not 111. 4 will be considered as 0100
The decimal number 3 is equal to the binary number 11. The binary
number 111 is equal to the decimal number 7. (The number of zeros
prepended to either number is irrelevant.)
and not 100.so if u r given a number , say 0xe7, which means
11100111,shift it to right by 4.
Huh? What on Earth are you talking about? Why would you do that?
int temp = array[3] >> 4;
which means
temp = 00001110 (= 0x0e)
int temp2 = array[3] << 4;
temp2 = 01110000 (0x70)
And what is that in aid of? What possible benefit can be gained by
changing 0xe7 to 0x7e?
similarly u can split up all the elements by shifting and get the 4 bit
equivalents. convert them to get the exact BCD no.
hope that was of some help.

I doubt very much that it was any help to anyone, I'm afraid.

--

Dig the even newer still, yet more improved, sig!

"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
Nov 14 '05 #15
Groovy hepcat Me was jivin' on 16 Jun 2005 21:30:13 -0700 in
comp.lang.c.
Re: Question converting unsigned char [] to int's a cool scene! Dig
it!
I have an unsigned char array (size 4):

unsigned char array[4];

array[0] = 0x00;
array[1] = 0x00;
array[2] = 0x02;
array[3] = 0xe7;

I would like to convert array[] to an integer.

0x00 0x00 0x02 0xe7 = 00000000 00000000 00000010 11100111 = 743

Any help is appreciated.

C doesn't guarantee that UCHAR_MAX <= UINT_MAX nor does it guarantee
that UINT_MAX is >= 0xFFFFFFFF. But here is something that will work if
you can guarantee the values in the array are <= 0xFF:

#define lengthof(a) (sizeof(a)/sizeof(a[0]))

const unsigned char array[4] = { 0, 0, 0x02, 0xe7 };
unsigned long ui = 0;
unsigned long mult = 1;

/*
it looks like you wanted big endian conversion. For little
endian, just index the array in the regular order
*/
for (unsigned i = 0; i < 4; ++i) {
ui += mult * array[lengthof(array)-1-i];
mult <<= 8;
}

Even better still (and tested):

#include <stdio.h>

int main(void)
{
unsigned char array[4] = {0, 0, 0x02, 0xe7};
unsigned long num;
int i;

num = 0;

for(i = 0; i < sizeof array; i++)
{
num <<= 8;
num |= array[i];
}

printf("num = %d\n", num);
return 0;
}

--

Dig the even newer still, yet more improved, sig!

"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
Nov 14 '05 #16
Peter Shaggy Haywood wrote:
.... snip ...
Even better still (and tested):

#include <stdio.h>

int main(void)
{
unsigned char array[4] = {0, 0, 0x02, 0xe7};
unsigned long num;
int i;

num = 0;

for(i = 0; i < sizeof array; i++)
{
num <<= 8;
num |= array[i];
num |= (array[i] & 0xff);
}

printf("num = %d\n", num);
return 0;
}

<nit> Assuming you don't know the byte size or the array contents
in advance, the above change will insulate things and ensure you
use octets. Otherwise you would be well advised to replace 8 by
CHAR_BIT and #include <limits.h>. </nit>

--
news:news.announce.newusers
http://www.geocities.com/nnqweb/
http://www.catb.org/~esr/faqs/smart-questions.html
http://www.caliburn.nl/topposting.html
http://www.netmeister.org/news/learn2quote.html
Nov 14 '05 #17

It's a perfect demonstration of KISS principle.
I won't forget this lesson :-)
On 19/06/2005 23:09, CBFalconer wrote:
Peter Shaggy Haywood wrote:

... snip ...

Even better still (and tested):

#include <stdio.h>

int main(void)
{
unsigned char array[4] = {0, 0, 0x02, 0xe7};
unsigned long num;
int i;

num = 0;

for(i = 0; i < sizeof array; i++)
{
num <<= 8;
num |= array[i];

num |= (array[i] & 0xff);
}

printf("num = %d\n", num);
return 0;
}

<nit> Assuming you don't know the byte size or the array contents
in advance, the above change will insulate things and ensure you
use octets. Otherwise you would be well advised to replace 8 by
CHAR_BIT and #include <limits.h>. </nit>

Nov 14 '05 #18
Jean-Claude Arbaut wrote:
On 19/06/2005 23:09, CBFalconer wrote:
Peter Shaggy Haywood wrote:

... snip ...

Even better still (and tested):

#include <stdio.h>

int main(void)
{
unsigned char array[4] = {0, 0, 0x02, 0xe7};
unsigned long num;
int i;

num = 0;
for(i = 0; i < sizeof array; i++) {
num <<= 8;
num |= array[i];

num |= (array[i] & 0xff);
}

printf("num = %d\n", num);
return 0;
}

<nit> Assuming you don't know the byte size or the array contents
in advance, the above change will insulate things and ensure you
use octets. Otherwise you would be well advised to replace 8 by
CHAR_BIT and #include <limits.h>. </nit>

It's a perfect demonstration of KISS principle.
I won't forget this lesson :-)

Top-posting fixed. Even clearer, make it:

for (i = 0; i < sizeof array; i++)
num = num * 256 + (array[i] & 0xff);

--
news:news.announce.newusers
http://www.geocities.com/nnqweb/
http://www.catb.org/~esr/faqs/smart-questions.html
http://www.caliburn.nl/topposting.html
http://www.netmeister.org/news/learn2quote.html

Nov 14 '05 #19

### This discussion thread is closed

Replies have been disabled for this discussion.