473,397 Members | 2,099 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,397 software developers and data experts.

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 26631
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

Nov 14 '05 #2
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.

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

Nov 14 '05 #7
ya*******@gmail.com 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
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
Martin Ambuhl <ma*****@earthlink.net> writes:
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:
Martin Ambuhl <ma*****@earthlink.net> writes:
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:
Martin Ambuhl <ma*****@earthlink.net> writes:
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
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"?
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!

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"?
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>

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

--
Some informative links:
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: hs | last post by:
Is the following correct? void foo(int len, char* val) { .. .. .. unsigned char* string = (unsigned char*) new char ; memcpy(string, val, len); ..
10
by: tinesan | last post by:
Hello fellow C programmers, I'm just learning to program with C, and I'm wondering what the difference between signed and unsigned char is. To me there seems to be no difference, and the...
14
by: mr_semantics | last post by:
I have been reading about the practise of casting values to unsigned char while using the <ctype.h> functions. For example, c = toupper ((unsigned char) c); Now I understand that the standard...
5
by: Stephen Cawood | last post by:
I'm trying to use a C++ .lib from C# (I tried the Interop group will no results). I have a working wrapper DLL (I can get back simple things like int), but I'm having issues dealing with an array...
2
by: bubzilla | last post by:
hi got a little prob with data types. I´m reading data from a socket in to a unsigned char buf; . Now, lets say there are 60Bytes written into the array( but it is always different). Now i...
11
by: hamishd | last post by:
Is this possible? Sorry if this question isn't relevant here. actually, I'm really trying to convert a unsigned char * to an int
4
by: HackerisNewKnight | last post by:
Hello, 1) First problem. In my project i need to convert from char* to BYTE*( BYTE is unsigned char), is there any way to make the convertion? BYTE* bite; char* ch="help me, please"; bite =...
12
by: Martin Wells | last post by:
I'm trying to come up with a fully-portable macro for supplying memset with an unsigned char rather than an int. I'm going to think out loud as I go along. . . I'll take a sample system before I...
5
by: Hans Mull | last post by:
Hi! How can I convert a string to a const unsigned char*? (string::c_str() converts the string to a signed char) Thanks in advance, Hans
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.