By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,173 Members | 1,049 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,173 IT Pros & Developers. It's quick & easy.

byte array and long??

P: n/a
hello!
I have a following situation:
I have a byte array where at a certain location are stored 4 bytes, and
these should be "put" into long variable (or any other 4 byte one).
ie:
byte a[]={0x0,0x0,0xfe,0x30,0x9e,0x2,0x66,0,0}
and the bytes 0xfe,0x30,0x9e,0x2 should be put into long variable which
should then contain 43921662
how to achieve this?

thanks!
Jul 22 '05 #1
Share this Question
Share on Google+
9 Replies


P: n/a

"w3r3w0lf" <as**@asdf.asdf> wrote in message
news:bv**********@ls219.htnet.hr...
hello!
I have a following situation:
I have a byte array where at a certain location are stored 4 bytes, and
these should be "put" into long variable (or any other 4 byte one).
ie:
byte a[]={0x0,0x0,0xfe,0x30,0x9e,0x2,0x66,0,0}
and the bytes 0xfe,0x30,0x9e,0x2 should be put into long variable which
should then contain 43921662
how to achieve this?

thanks!


This *might* work,

long x = *reinterpret_cast<long*>(a + 2);

but if it doesn't it is because you have to swap the bytes around.

byte tmp[4] = { a[5], a[4], a[3], a[2] }; // swap bytes
long x = *reinterpret_cast<long*>(tmp);

john
Jul 22 '05 #2

P: n/a
On Tue, 3 Feb 2004 22:28:38 -0000, "John Harrison"
<jo*************@hotmail.com> wrote in comp.lang.c++:

"w3r3w0lf" <as**@asdf.asdf> wrote in message
news:bv**********@ls219.htnet.hr...
hello!
I have a following situation:
I have a byte array where at a certain location are stored 4 bytes, and
these should be "put" into long variable (or any other 4 byte one).
ie:
byte a[]={0x0,0x0,0xfe,0x30,0x9e,0x2,0x66,0,0}
and the bytes 0xfe,0x30,0x9e,0x2 should be put into long variable which
should then contain 43921662
how to achieve this?

thanks!


This *might* work,

long x = *reinterpret_cast<long*>(a + 2);

but if it doesn't it is because you have to swap the bytes around.

byte tmp[4] = { a[5], a[4], a[3], a[2] }; // swap bytes
long x = *reinterpret_cast<long*>(tmp);

john


But it will fail on an ARM (and some other processors) with an
addressing fault due to improper alignment.

It will fail on a TI 320F28xx because the long will contain 0x003000fe
which is not what the OP asked for.

And in fact it is undefined behavior on any
platform/architecture/implementation.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Jul 22 '05 #3

P: n/a
"w3r3w0lf" <as**@asdf.asdf> wrote in message
news:bv**********@ls219.htnet.hr...
hello!
I have a following situation:
I have a byte array where at a certain location are stored 4 bytes, and
these should be "put" into long variable (or any other 4 byte one).
ie:
byte a[]={0x0,0x0,0xfe,0x30,0x9e,0x2,0x66,0,0}
and the bytes 0xfe,0x30,0x9e,0x2 should be put into long variable which
should then contain 43921662
how to achieve this?

thanks!


try this and tell me if this works!

#include <iostream>
using namespace std;

int main(){
char a[] = {0x0,0x0,0xfe,0x30,0x9e,0x2,0x66,0,0};
long b=0;

memcpy(&b,&a[2], sizeof(4));

cout << b << endl;
cin.get();
}

~ Let us linux ~
-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 100,000 Newsgroups - 19 Different Servers! =-----
Jul 22 '05 #4

P: n/a

"Jack Klein" <ja*******@spamcop.net> wrote in message
news:1h********************************@4ax.com...
On Tue, 3 Feb 2004 22:28:38 -0000, "John Harrison"
<jo*************@hotmail.com> wrote in comp.lang.c++:

"w3r3w0lf" <as**@asdf.asdf> wrote in message
news:bv**********@ls219.htnet.hr...
hello!
I have a following situation:
I have a byte array where at a certain location are stored 4 bytes, and these should be "put" into long variable (or any other 4 byte one).
ie:
byte a[]={0x0,0x0,0xfe,0x30,0x9e,0x2,0x66,0,0}
and the bytes 0xfe,0x30,0x9e,0x2 should be put into long variable which should then contain 43921662
how to achieve this?

thanks!


This *might* work,

long x = *reinterpret_cast<long*>(a + 2);

but if it doesn't it is because you have to swap the bytes around.

byte tmp[4] = { a[5], a[4], a[3], a[2] }; // swap bytes
long x = *reinterpret_cast<long*>(tmp);

john


But it will fail on an ARM (and some other processors) with an
addressing fault due to improper alignment.

It will fail on a TI 320F28xx because the long will contain 0x003000fe
which is not what the OP asked for.

And in fact it is undefined behavior on any
platform/architecture/implementation.


I never claimed my answer was platform independent. A truly platform
independent answer is surprisingly difficult. Perhaps you could oblige the
OP with such an answer?

John
Jul 22 '05 #5

P: n/a
On Tue, 03 Feb 2004 23:19:35 +0100, w3r3w0lf wrote:
hello!
I have a following situation:
I have a byte array where at a certain location are stored 4 bytes, and
these should be "put" into long variable (or any other 4 byte one).
ie:
byte a[]={0x0,0x0,0xfe,0x30,0x9e,0x2,0x66,0,0}
and the bytes 0xfe,0x30,0x9e,0x2 should be put into long variable which
should then contain 43921662
how to achieve this?


Assuming unsigned char for byte, this should work portably and safely:

long l = 0;

for (size_t ix=5; ix>1; ++ix) {
l <<= 8;
l |= a[ix];
}

If byte is signed, stick in a cast to unsigned char.

HTH,
M4

Jul 22 '05 #6

P: n/a

"Martijn Lievaart" <m@remove.this.part.rtij.nl> wrote in message
news:pa****************************@remove.this.pa rt.rtij.nl...
On Tue, 03 Feb 2004 23:19:35 +0100, w3r3w0lf wrote:
hello!
I have a following situation:
I have a byte array where at a certain location are stored 4 bytes, and
these should be "put" into long variable (or any other 4 byte one).
ie:
byte a[]={0x0,0x0,0xfe,0x30,0x9e,0x2,0x66,0,0}
and the bytes 0xfe,0x30,0x9e,0x2 should be put into long variable which
should then contain 43921662
how to achieve this?


Assuming unsigned char for byte, this should work portably and safely:

long l = 0;

for (size_t ix=5; ix>1; ++ix) {
l <<= 8;
l |= a[ix];
}

If byte is signed, stick in a cast to unsigned char.

HTH,
M4


Sorry to be pedantic, but it assumes 8 bits for char. Replace 8 with
CHAR_BIT from <limits.h>.

Also to be extremely pedantic I don't think that the standard gives any
guarantees and to the 'mathematical' behaviour of << when the left argument
is long (unsigned long would be different). So there is no guarantee that l
<<= 8 is the same as l *= 256. But if you were to replace l <<= 8 with l *=
256 then you would run into undefined behaviour because of the potential
overflow (again it would be different with unsigned long). At least that's
how I remember it, as usual I can't find the reference in the standard.

Sometimes it seems to me that the standard makes simple things very
difficult.

john
Jul 22 '05 #7

P: n/a
On Wed, 04 Feb 2004 08:15:30 +0000, John Harrison wrote:

Assuming unsigned char for byte, this should work portably and safely:

long l = 0;

for (size_t ix=5; ix>1; ++ix) {
l <<= 8;
l |= a[ix];
}

If byte is signed, stick in a cast to unsigned char.

Sorry to be pedantic, but it assumes 8 bits for char. Replace 8 with
CHAR_BIT from <limits.h>.


Good point, but actually depends on the input. If the input is octets
(which is quite likely, most of the world talks octets, 8 is correct.
Also to be extremely pedantic I don't think that the standard gives any
guarantees and to the 'mathematical' behaviour of << when the left argument
is long (unsigned long would be different). So there is no guarantee that l
<<= 8 is the same as l *= 256. But if you were to replace l <<= 8 with l *=
256 then you would run into undefined behaviour because of the potential
overflow (again it would be different with unsigned long). At least that's
how I remember it, as usual I can't find the reference in the standard.
Right.

5.8 clause two. A left shift shifts left the bit pattern making up the
object. The reference to bitpattern makes it clear that this is
implementation defined for signed. It even explicitly states that it has
defined behaviour for unsigned integers.

5 clause 5. All overflows result in UB. So if the shift-left or the *256
results in a (signed) long that would be greater than LONG_MAX, we enter
UB.

3.9.1 clause 4. All unsigned integer types shall obey modulo-2 arithmetic.

3.9.1 clause 3. The bitpatterns for positive signed integers are the same
as their unsigned counterpart.

So left-shifting works only with unsigned long, and with signed long when
the input results in a positive number <= LONG_MAX. It is also guarenteed
to work with negative longs if you know for a fact that your machine uses
2's-complement arithmetic, which is a non-portable assumption.

Also, if the original bit pattern originated on the same machine, the
left-shift solution is required to work with signed long, however, in that
case this is musch simpler:

long l;
memcpy(&l, a+2, sizeof(long));

Multiplying with 256 works for unsigned long, and with signed long when
the input results in a positive number <= LONG_MAX. In practice it will
work with 2's-complement, but contrary to left-shifting the standard does
not guarentee that.

Another point to note, is that the standard probably only guarentees the
result if the type byte is an unsigned type. If the type byte is a signed
char for instance:

l |= a[ix];

would convert a[ix] to a signed long, hardly what you want.

l |= static_cast<unsigned char>(a[ix]);

Makes 4.7 clause 2 apply:

"2 If the destination type is unsigned, the resulting value is the least
unsigned integer congruent to the source integer (modulo 2n where n is the
number of bits used to represent the unsigned type). [Note: In a two s
complement representation, this conversion is conceptual and there is no
change in the bit pattern (if there is no truncation). ]"

Which I don't understand, but clearly implies the bit pattern can change
on non-2's-complement machines.
Sometimes it seems to me that the standard makes simple things very
difficult.


Yup. OTOH, this stuff /is/ difficult. Use text formats or network-order if
portability is an issue. If using network order, unly use it for unsigned
types.

M4

Jul 22 '05 #8

P: n/a
On Wed, 04 Feb 2004 07:51:23 +0000, John Harrison wrote:
> This *might* work,
>
> long x = *reinterpret_cast<long*>(a + 2);
>
> but if it doesn't it is because you have to swap the bytes around.
>
> byte tmp[4] = { a[5], a[4], a[3], a[2] }; // swap bytes
> long x = *reinterpret_cast<long*>(tmp);
>
> john
But it will fail on an ARM (and some other processors) with an
addressing fault due to improper alignment.

It will fail on a TI 320F28xx because the long will contain 0x003000fe
which is not what the OP asked for.

And in fact it is undefined behavior on any
platform/architecture/implementation.


I never claimed my answer was platform independent. A truly platform


No, but you indicated that it could fail due to byte order, where it can
in fact crash.
independent answer is surprisingly difficult. Perhaps you could oblige the
OP with such an answer?


See the other subthread, where a better answer is discussed. To truly
answer the question, we should know more about the input and context.

HTH,
M4

Jul 22 '05 #9

P: n/a
w3r3w0lf wrote in news:bv**********@ls219.htnet.hr:
hello!
I have a following situation:
I have a byte array where at a certain location are stored 4 bytes, and
these should be "put" into long variable (or any other 4 byte one).
ie:
byte a[]={0x0,0x0,0xfe,0x30,0x9e,0x2,0x66,0,0}
and the bytes 0xfe,0x30,0x9e,0x2 should be put into long variable which
should then contain 43921662
how to achieve this?


#include <iostream>
#include <limits>

typedef unsigned char byte;

byte a[]={0x0,0x0,0xfe,0x30,0x9e,0x2,0x66,0,0};
byte m[] = { 0xB2, 0x9E, 0x43, 0xFF }; /* -12345678 */

long four_bytes_to_long( byte const *bp )
{
unsigned long ul =
( bp[0] * 1UL ) +
( bp[1] * 256UL ) +
( bp[2] * 256UL * 256UL ) +
( bp[3] * 256UL * 256UL * 256UL )
;

unsigned long const lmax = std::numeric_limits< long >::max();

return ( ul > lmax ) ? -long(~ul + 1) : long( ul );
}

int main()
{
std::cerr << four_bytes_to_long( a + 2 ) << '\n';
std::cerr << four_bytes_to_long( m ) << '\n';
}

HTH.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #10

This discussion thread is closed

Replies have been disabled for this discussion.