CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 12 of 12
  1. #1
    Join Date
    Dec 2005
    Posts
    382

    storing unsigned short value into a byte array

    Trying to understand what appeared to have been frustration on the part of two coworkers.

    Consider:

    Code:
    typedef std::vector < char > CHAR_VEC ;
    int main() 
    {
    
      CHAR_VEC uv ( 2 ) ;
      char *ptr_buffer = &uv [ 0 ];
      typedef unsigned short ushort_type ; 
      ushort_type value = 0x9C2C ; 
      *ptr_buffer++ = ( value & 0xFF ) ; 
      *ptr_buffer++ = value >> 8 ;   
      for ( std::size_t odx ( 0 ); odx < uv.size(); ++odx ) 
        std::cout << std::hex << static_cast < int > ( uv [ odx ] ) << '\n';
    
      std::cin.get() ;
    }

    The result on my implementation:
    0x2c
    0xffffff9c

    1)
    For starters, I'm not sure how serialization entered the dicussion but in my view storing unsigned shorts into byte arrays does not equate to serialization. You ask me the array would have to be 4 deep and the contents equate to:
    uv[ 0 ] = 'C'
    uv[ 1 ] = '2'
    uv[ 2 ] = 'C'
    uv[ 3 ] = '9'
    for serialization. True/False?

    2) The value 9C stored when stored in the character array results in: 0xffffff9c. 0x9C is obviously too large for the type. 0x9C is 156 and 0xffffff9c is -100. Two questions:
    a) is this an issue of 'overflow' or is this just simply an issue where the value is too large for the type?
    b) I thought the difference 127-156 (-29) would be the end result that gets stored in location. Why -100?

  2. #2
    Join Date
    Nov 2003
    Posts
    1,902

    Re: storing unsigned short value into a byte array

    That's just sign extension. You want:

    std::cout << std::hex << (unsigned)(unsigned char)uv[odx] << '\n';

    gg

  3. #3
    Join Date
    Dec 2005
    Posts
    382

    Re: storing unsigned short value into a byte array

    Quote Originally Posted by Codeplug View Post
    That's just sign extension. You want:

    std::cout << std::hex << (unsigned)(unsigned char)uv[odx] << '\n';

    gg
    Interesting .. Here's where I'm confused. The value 156 can't fit in a char or is it being treated as 'text'.. ?

  4. #4
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: storing unsigned short value into a byte array

    Quote Originally Posted by mop65715 View Post
    is this an issue of 'overflow' or is this just simply an issue where the value is too large for the type?
    Technically it is overflow, although one doesn't usually think of it that way in the case of chars. it's just that the same bit pattern which would represent "156" in an unsigned char is interpreted as "-100" in a signed char. Often one doesn't really care about the interpretation, only the underlying bit pattern, when dealing with chars.

    b) I thought the difference 127-156 (-29) would be the end result that gets stored in location. Why -100?
    The difference you're looking for is from 256, not from 127. The bit pattern 0x80 is -128. That's just how twos-complement works. Just like 0x7F is 127, 0xFF is -1, etc.

  5. #5
    Join Date
    Dec 2005
    Posts
    382

    Re: storing unsigned short value into a byte array

    Quote Originally Posted by Lindley View Post
    Technically it is overflow, although one doesn't usually think of it that way in the case of chars. it's just that the same bit pattern which would represent "156" in an unsigned char is interpreted as "-100" in a signed char. Often one doesn't really care about the interpretation, only the underlying bit pattern, when dealing with chars.



    The difference you're looking for is from 256, not from 127. The bit pattern 0x80 is -128. That's just how twos-complement works. Just like 0x7F is 127, 0xFF is -1, etc.
    Excellent! Could you elaborate on item 1 for me?

  6. #6
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: storing unsigned short value into a byte array

    Quote Originally Posted by mop65715 View Post
    1)
    For starters, I'm not sure how serialization entered the dicussion but in my view storing unsigned shorts into byte arrays does not equate to serialization. You ask me the array would have to be 4 deep and the contents equate to:
    uv[ 0 ] = 'C'
    uv[ 1 ] = '2'
    uv[ 2 ] = 'C'
    uv[ 3 ] = '9'
    for serialization. True/False?
    Since a short is 2 bytes, you could serialize a short into only 2 chars if you wanted. I think you need to make the distinction between serialization, which is any robust, reversible means of representing an object as an array of bytes; and output, which typically must be human-readable. Serialization usually doesn't need to be human-readable, although it may be.

  7. #7
    Join Date
    Nov 2003
    Posts
    1,902

    Re: storing unsigned short value into a byte array

    I don't think "overflow" is the right term to use here. "Overflow" implies "arithmetic overflow" in my mind. Technically it's "sign extension".

    signed char and unsigned char are both 8 bits - so can hold 0x00 to 0xFF. signed vs. unsigned just changes the interpretation of those bits, as Lindley pointed out.

    operator << is for formatted output. When you pass it any kind of char, it's interpreted as a character. This is why you have to cast it to an integer in order for operator << to display an integer. When you cast from unsigned char to any-sign int, you get sign extension (to preserve the negative-ness). That's why you have to cast to unsigned char first, then to int.

    gg

  8. #8
    Join Date
    Dec 2005
    Posts
    382

    Re: storing unsigned short value into a byte array

    [QUOTE=Lindley;1883207]Since a short is 2 bytes, you could serialize a short into only 2 chars if you wanted. QUOTE]

    Just so I'm clear. As in (?):
    Code:
    uv[ 0 ] = 'C'
    uv[ 1 ] = '2'
    uv[ 2 ] = 'C'
    uv[ 3 ] = '9'
    OR

    Code:
    uv[ 0 ] = 0x2C
    uv[ 1 ] = 0x9C

  9. #9
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: storing unsigned short value into a byte array

    Yes, although when you condense it the second way, then the endianness of the machine becomes a concern. It's just something to bear in mind.

  10. #10
    Join Date
    Nov 2003
    Posts
    1,902

    Re: storing unsigned short value into a byte array

    'uv' is a vector of char's. A char is 1 byte or 8 bits. Each index into uv represents a single char. So the first example is setting 4 bytes. The second example is setting 2 bytes.

    The character 'C' is equivalent to 0x43.

    gg

  11. #11
    Join Date
    Dec 2005
    Posts
    382

    Re: storing unsigned short value into a byte array

    Quote Originally Posted by Lindley View Post
    Yes, although when you condense it the second way, then the endianness of the machine becomes a concern. It's just something to bear in mind.

    You and Codeplug have been a blessing. Almost there! So bottom line is: Endian issues between machines is a 'non issue' with the first approach. The 'cost' though is 4 bytes.. ( a factor of 2 difference using my contrived example)

  12. #12
    Join Date
    Nov 2003
    Posts
    1,902

    Re: storing unsigned short value into a byte array

    Code:
      *ptr_buffer++ = ( value & 0xFF ) ; 
      *ptr_buffer++ = value >> 8 ;
    Since each byte is extracted individually, there is no endian issue. When you de-serialize, just put the bytes back where you found them.

    If you tried to read or write 'value' as an array of bytes in memory, then you'll have endian issues.

    gg

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured