byte array and long??

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • w3r3w0lf

    byte array and long??

    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,0 x66,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!


  • John Harrison

    #2
    Re: byte array and long??


    "w3r3w0lf" <asff@asdf.asdf > wrote in message
    news:bvp6si$hmf $1@ls219.htnet. hr...[color=blue]
    > 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,0 x66,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!
    >[/color]

    This *might* work,

    long x = *reinterpret_ca st<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_ca st<long*>(tmp);

    john


    Comment

    • Jack Klein

      #3
      Re: byte array and long??

      On Tue, 3 Feb 2004 22:28:38 -0000, "John Harrison"
      <john_andronicu s@hotmail.com> wrote in comp.lang.c++:
      [color=blue]
      >
      > "w3r3w0lf" <asff@asdf.asdf > wrote in message
      > news:bvp6si$hmf $1@ls219.htnet. hr...[color=green]
      > > 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,0 x66,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!
      > >[/color]
      >
      > This *might* work,
      >
      > long x = *reinterpret_ca st<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_ca st<long*>(tmp);
      >
      > john[/color]

      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.l earn.c-c++

      Comment

      • rolo

        #4
        Re: byte array and long??

        "w3r3w0lf" <asff@asdf.asdf > wrote in message
        news:bvp6si$hmf $1@ls219.htnet. hr...[color=blue]
        > 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,0 x66,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!
        >
        >[/color]

        try this and tell me if this works!

        #include <iostream>
        using namespace std;

        int main(){
        char a[] = {0x0,0x0,0xfe,0 x30,0x9e,0x2,0x 66,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! =-----

        Comment

        • John Harrison

          #5
          Re: byte array and long??


          "Jack Klein" <jackklein@spam cop.net> wrote in message
          news:1hq020doaj g68j62n6057dki4 s1lceb0d4@4ax.c om...[color=blue]
          > On Tue, 3 Feb 2004 22:28:38 -0000, "John Harrison"
          > <john_andronicu s@hotmail.com> wrote in comp.lang.c++:
          >[color=green]
          > >
          > > "w3r3w0lf" <asff@asdf.asdf > wrote in message
          > > news:bvp6si$hmf $1@ls219.htnet. hr...[color=darkred]
          > > > hello!
          > > > I have a following situation:
          > > > I have a byte array where at a certain location are stored 4 bytes,[/color][/color][/color]
          and[color=blue][color=green][color=darkred]
          > > > these should be "put" into long variable (or any other 4 byte one).
          > > > ie:
          > > > byte a[]={0x0,0x0,0xfe, 0x30,0x9e,0x2,0 x66,0,0}
          > > > and the bytes 0xfe,0x30,0x9e, 0x2 should be put into long variable[/color][/color][/color]
          which[color=blue][color=green][color=darkred]
          > > > should then contain 43921662
          > > > how to achieve this?
          > > >
          > > > thanks!
          > > >[/color]
          > >
          > > This *might* work,
          > >
          > > long x = *reinterpret_ca st<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_ca st<long*>(tmp);
          > >
          > > john[/color]
          >
          > 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.
          >[/color]

          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


          Comment

          • Martijn Lievaart

            #6
            Re: byte array and long??

            On Tue, 03 Feb 2004 23:19:35 +0100, w3r3w0lf wrote:
            [color=blue]
            > 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,0 x66,0,0}
            > and the bytes 0xfe,0x30,0x9e, 0x2 should be put into long variable which
            > should then contain 43921662
            > how to achieve this?[/color]

            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

            Comment

            • John Harrison

              #7
              Re: byte array and long??


              "Martijn Lievaart" <m@remove.this. part.rtij.nl> wrote in message
              news:pan.2004.0 2.04.07.58.39.6 80809@remove.th is.part.rtij.nl ...[color=blue]
              > On Tue, 03 Feb 2004 23:19:35 +0100, w3r3w0lf wrote:
              >[color=green]
              > > 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,0 x66,0,0}
              > > and the bytes 0xfe,0x30,0x9e, 0x2 should be put into long variable which
              > > should then contain 43921662
              > > how to achieve this?[/color]
              >
              > 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
              >[/color]

              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


              Comment

              • Martijn Lievaart

                #8
                Re: byte array and long??

                On Wed, 04 Feb 2004 08:15:30 +0000, John Harrison wrote:
                [color=blue][color=green]
                >>
                >> 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.
                >>[/color]
                >
                > Sorry to be pedantic, but it assumes 8 bits for char. Replace 8 with
                > CHAR_BIT from <limits.h>.[/color]

                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.
                [color=blue]
                > 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.[/color]

                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<uns igned 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.
                [color=blue]
                > Sometimes it seems to me that the standard makes simple things very
                > difficult.[/color]

                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

                Comment

                • Martijn Lievaart

                  #9
                  Re: byte array and long??

                  On Wed, 04 Feb 2004 07:51:23 +0000, John Harrison wrote:
                  [color=blue][color=green][color=darkred]
                  >> > This *might* work,
                  >> >
                  >> > long x = *reinterpret_ca st<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_ca st<long*>(tmp);
                  >> >
                  >> > john[/color]
                  >>
                  >> 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.
                  >>[/color]
                  >
                  > I never claimed my answer was platform independent. A truly platform[/color]

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

                  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

                  Comment

                  • Rob Williscroft

                    #10
                    Re: byte array and long??

                    w3r3w0lf wrote in news:bvp6si$hmf $1@ls219.htnet. hr:
                    [color=blue]
                    > 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,0 x66,0,0}
                    > and the bytes 0xfe,0x30,0x9e, 0x2 should be put into long variable which
                    > should then contain 43921662
                    > how to achieve this?
                    >[/color]

                    #include <iostream>
                    #include <limits>

                    typedef unsigned char byte;

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

                    long four_bytes_to_l ong( 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_li mits< long >::max();

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

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

                    HTH.

                    Rob.
                    --

                    Comment

                    Working...