Conversion between datatypes on basis of blocks of bytes

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • AmberJain
    Recognized Expert Contributor
    • Jan 2008
    • 922

    Conversion between datatypes on basis of blocks of bytes

    I have an array of 32 elements of type 'unsigned char' (i.e. 32 bytes).
    I'll like to store first 4 bytes of this array in a 'unsigned long', next 4 bytes in another 'unsigned long' and so on. Any ideas about how do I perform this?

    I'm personally thinking that I need to do something like left shifting and then masking repeatedly but I don't get it right.

    Another idea in my mind is to use uint32_t (C99) for this purpose. But I'm confused here too.

    Any ideas?
    Last edited by Niheel; May 6 '10, 10:39 PM. Reason: removed unnecessary question details
  • hype261
    New Member
    • Apr 2010
    • 207

    #2
    reinterpret_cas t

    Couldn't you just do a reinterpret_cas t to go from one type to another?

    unsigned char a[32];

    unsigned long * b = reinterpret_cas t<unsigned long*>(a);

    and then access it like
    b[0], b[1], b[2], b[3]

    Comment

    • donbock
      Recognized Expert Top Contributor
      • Mar 2008
      • 2427

      #3
      Are you required to match any particular endianness when you pack the bytes into larger integers?

      Comment

      • AmberJain
        Recognized Expert Contributor
        • Jan 2008
        • 922

        #4
        Originally posted by donbock
        Are you required to match any particular endianness when you pack the bytes into larger integers?
        No.
        But I'm on little endian (intel) if this info is needed.

        Comment

        • AmberJain
          Recognized Expert Contributor
          • Jan 2008
          • 922

          #5
          Originally posted by hype261
          Couldn't you just do a reinterpret_cas t to go from one type to another?
          Isn't reinterpret_cas t only for C++? because I had never done so in C. Please correct me if I'm wrong.

          And yeah, I'm writing code in C for this task.

          Comment

          • hype261
            New Member
            • Apr 2010
            • 207

            #6
            Yes reinterpret_cas t is a C++ convention, but if you are just using C then a regular cast should do the trick

            unsigned long * b = (unsigned long *)a;

            Comment

            • donbock
              Recognized Expert Top Contributor
              • Mar 2008
              • 2427

              #7
              Some machines have alignment restrictions for wider integer types like short or long. The pointer-cast approach described above will raise an exception on such a machine unless you are careful about alignment.

              You can avoid alignment problems by copying bytes from your big byte array into a union. I've seen this done a lot, but the results are certainly implementation dependent. I think you're relying on undefined behavior, and that's always a bad idea.
              Code:
              union ab {
                 unsigned char a[4];
                 long b;
                 };
              The most reliable and portable way to do this is to start with a clear specification how the byte stream relates to the wider integer types, especially endianness and representation of negative values. They write software that explicitly implements the specification without relying on your machine happening to match the specification.

              For example, if your specification says negative numbers are represented in the byte stream using two's-complement, then assemble the bytes in an unsigned type, test the sign bit, if it is set then use explicit logic to negate it (convert it to the equivalent positive number by inverting the bits and adding one), copy the positive value to a signed variable, and then use the unary-minus operator to negate it. This should work regardless of whether your machine uses two's-complement representation or not.

              Comment

              • AmberJain
                Recognized Expert Contributor
                • Jan 2008
                • 922

                #8
                Thank you.

                Comment

                Working...