Question converting unsigned char [] to int

N

No Such Luck

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.
 
Y

yatindran

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.

badri
 
M

Me

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.
 
J

junky_fellow

Me said:
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.
 
M

Martin Ambuhl

No said:
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
 
M

Me

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.
 
R

Richard Bos

(e-mail address removed) wrote:

[ If you _must_ use Google Broken Beta to post to Usenet, could you
please ensure that you quote something when you reply? Instructions
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
 
P

pete

Martin said:
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.
 
L

Lawrence Kirby

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;
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
 
M

Martin Ambuhl

pete said:
Martin said:
No said:
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.
 
T

Tim Rentsch

Martin Ambuhl said:
No said:
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.
 
O

Old Wolf

Tim said:
Martin Ambuhl said:
No said:
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).
 
T

Tim Rentsch

Old Wolf said:
Tim said:
Martin Ambuhl said:
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.
 
P

Peter Shaggy Haywood

Groovy hepcat (e-mail address removed) 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!

Please provide context by quoting (the relevant portions of) the
post to which you are following up. Also, do not use d00dspeak-isms
like "u" instead of "you" and "r" instead of "are". And please, please
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!

http://alphalink.com.au/~phaywood/
"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"?
 
P

Peter Shaggy Haywood

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;
}

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

--

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

http://alphalink.com.au/~phaywood/
"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"?
 
C

CBFalconer

Peter said:
.... 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;


num |= (array & 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>

--
Some informative links:
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
 
J

Jean-Claude Arbaut

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


... 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;


num |= (array & 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>
 
C

CBFalconer

Jean-Claude Arbaut said:
... 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;


num |= (array & 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 & 0xff);

--
Some informative links:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top