Convert short to byte array

Discussion in 'C++' started by porcelli.giuseppe@gmail.com, Feb 28, 2013.

  1. Guest

    Sorry for this stupid question by I am very new to C++

    how to convert this routine to C++ ?

    private byte[] getByteFromShort(short x) {
    byte[] a = new byte[2];
    a[0] = (byte) (x & 0xff);
    a[1] = (byte) ((x >> 8) & 0xff);
    return a;
    }

    Thank you.
     
    , Feb 28, 2013
    #1
    1. Advertising

  2. On 2/28/2013 2:21 PM, wrote:
    > Sorry for this stupid question by I am very new to C++
    >
    > how to convert this routine to C++ ?
    >
    > private byte[] getByteFromShort(short x) {
    > byte[] a = new byte[2];
    > a[0] = (byte) (x & 0xff);
    > a[1] = (byte) ((x >> 8) & 0xff);
    > return a;
    > }


    It's almost in C++ already. Literal translation might look like this:

    typedef unsigned char byte;
    ....
    byte* getByteFromShort(short x) {
    byte* a = new byte[2];
    a[0] = x & 0xff;
    a[1] = (x >> 8) & 0xff;
    return a;
    }

    Managing access level ('private', 'public' or 'protected') is left to
    the reader.

    Now, whether this fits your needs, I don't know, you didn't explain how
    this function is going to be used.

    V
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Feb 28, 2013
    #2
    1. Advertising

  3. Nobody Guest

    On Thu, 28 Feb 2013 11:21:55 -0800, porcelli.giuseppe wrote:

    > Sorry for this stupid question by I am very new to C++
    >
    > how to convert this routine to C++ ?
    >
    > private byte[] getByteFromShort(short x) {
    > byte[] a = new byte[2];
    > a[0] = (byte) (x & 0xff);
    > a[1] = (byte) ((x >> 8) & 0xff);
    > return a;
    > }


    Bare (C-style) arrays can't be returned by value. You need to use
    e.g. std::array (std::tr1::array prior to C++11), e.g.:

    std::array<uint8_t, 2> getByteFromShort(uint16_t x) {
    std::array<uint8_t, 2> a;
    a[0] = (uint8_t) (x & 0xff);
    a[1] = (uint8_t) ((x >> 8) & 0xff);
    return a;
    }

    If you really want to use a bare array, have the caller pass it in:

    void getByteFromShort(uint16_t x, uint8_t a[2]) {
    a[0] = (uint8_t) (x & 0xff);
    a[1] = (uint8_t) ((x >> 8) & 0xff);
    }

    Note 1: although C++ has a "short" type, it's not guaranteed to be
    exactly 16 bits. It is guaranteed to be at least 16 bits.

    Note 2: Signed integral types aren't guaranteed to use two's-complement
    representation. The result of performing a right shift on a negative
    integer is implementation-defined.

    Fortunately, all C++ integral types have both signed and unsigned
    versions, so you aren't coerced into using signed integers inappropriately
    (unlike in Java).
     
    Nobody, Feb 28, 2013
    #3
  4. On 2/28/2013 4:43 PM, Nobody wrote:
    > On Thu, 28 Feb 2013 11:21:55 -0800, porcelli.giuseppe wrote:
    >
    >> Sorry for this stupid question by I am very new to C++
    >>
    >> how to convert this routine to C++ ?
    >>
    >> private byte[] getByteFromShort(short x) {
    >> byte[] a = new byte[2];
    >> a[0] = (byte) (x & 0xff);
    >> a[1] = (byte) ((x >> 8) & 0xff);
    >> return a;
    >> }

    >
    > Bare (C-style) arrays can't be returned by value. You need to use
    > e.g. std::array (std::tr1::array prior to C++11), e.g.:
    >
    > std::array<uint8_t, 2> getByteFromShort(uint16_t x) {
    > std::array<uint8_t, 2> a;
    > a[0] = (uint8_t) (x & 0xff);
    > a[1] = (uint8_t) ((x >> 8) & 0xff);
    > return a;
    > }
    >
    > If you really want to use a bare array, have the caller pass it in:
    >
    > void getByteFromShort(uint16_t x, uint8_t a[2]) {


    To the OP: this is a bit dangerous. The second argument is an address
    of a 'uint8_t' value, but there is no guarantee that it points to an
    array of two such values (so the index 1 can be used), and there is no
    way for the compiler to verify that. I would probably recommend passing
    this array by reference:

    void getByteFromShort(uint16_t x, uint8_t (&a)[2]) {

    > a[0] = (uint8_t) (x & 0xff);
    > a[1] = (uint8_t) ((x >> 8) & 0xff);
    > }
    >
    > [..]


    V
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Feb 28, 2013
    #4
  5. On 3/1/2013 11:22 AM, Juha Nieminen wrote:
    > Victor Bazarov <> wrote:
    >> It's almost in C++ already. Literal translation might look like this:
    >>
    >> typedef unsigned char byte;
    >> ...
    >> byte* getByteFromShort(short x) {
    >> byte* a = new byte[2];
    >> a[0] = x & 0xff;
    >> a[1] = (x >> 8) & 0xff;
    >> return a;
    >> }

    >
    > Given that you are a frequent visitor of this newsgroup and you probably
    > know C++ better than the average programmer, I find it extremely puzzling
    > why you would recommend such a horrible, horrible solution to the question
    > that was posed.


    (a) You didn't provide *any* solution.

    (b) You haven't bothered to explain (to those who need an explanation,
    like the OP, for instance) why you consider this solution horrible.

    Given that such an attitude is frequent in your posts, I find it no
    surprise whatsoever why you would continue posting in this manner.

    V
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Mar 1, 2013
    #5
  6. On 3/1/2013 4:23 PM, Christian Gollwitzer wrote:
    > Am 01.03.13 17:55, schrieb Victor Bazarov:
    >> On 3/1/2013 11:22 AM, Juha Nieminen wrote:
    >>> Victor Bazarov <> wrote:
    >>>> It's almost in C++ already. Literal translation might look like this:
    >>>>
    >>>> typedef unsigned char byte;
    >>>> ...
    >>>> byte* getByteFromShort(short x) {
    >>>> byte* a = new byte[2];
    >>>> a[0] = x & 0xff;
    >>>> a[1] = (x >> 8) & 0xff;
    >>>> return a;
    >>>> }

    >
    >>> why you would recommend such a horrible, horrible solution

    >
    >> (b) You haven't bothered to explain (to those who need an explanation,
    >> like the OP, for instance) why you consider this solution horrible.

    >
    > Well, I think that is pretty clear: your solution returns a newly
    > allocated buffer by pointer. That calls for manual memory management. If
    > one considers that a pointer in today's computers takes up at least four
    > bytes, it is also less efficient than returning the two bytes by value
    > in a structure. Even doing an inline function like this might be more
    > efficient:
    >
    > unsigned char getByteFromShort(short x, size_t i) {
    > if (i==0) return x & 0xff;
    > if (i==1) return (x>>8) & =xff;
    > throw std::eek:ut_of_range("Index in short must be 0 or 1");
    > }


    There is a very big assumption concerning the way this function is
    supposed to be used. Your crystal ball must be in much better order
    than mine if you can divine what the OP wanted (as you clearly do here).

    V
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Mar 1, 2013
    #6
  7. Ian Collins Guest

    Christian Gollwitzer wrote:
    > Am 01.03.13 17:55, schrieb Victor Bazarov:
    >> On 3/1/2013 11:22 AM, Juha Nieminen wrote:
    >>> Victor Bazarov <> wrote:
    >>>> It's almost in C++ already. Literal translation might look like this:
    >>>>
    >>>> typedef unsigned char byte;
    >>>> ...
    >>>> byte* getByteFromShort(short x) {
    >>>> byte* a = new byte[2];
    >>>> a[0] = x & 0xff;
    >>>> a[1] = (x >> 8) & 0xff;
    >>>> return a;
    >>>> }

    >
    >>> why you would recommend such a horrible, horrible solution

    >
    >> (b) You haven't bothered to explain (to those who need an explanation,
    >> like the OP, for instance) why you consider this solution horrible.

    >
    > Well, I think that is pretty clear: your solution returns a newly
    > allocated buffer by pointer. That calls for manual memory management. If
    > one considers that a pointer in today's computers takes up at least four
    > bytes, it is also less efficient than returning the two bytes by value
    > in a structure.


    Why?

    > Even doing an inline function like this might be more
    > efficient:
    >
    > unsigned char getByteFromShort(short x, size_t i) {
    > if (i==0) return x & 0xff;
    > if (i==1) return (x>>8) & =xff;
    > throw std::eek:ut_of_range("Index in short must be 0 or 1");
    > }


    So you propose a "safe" solution that doesn't do what the OP wanted (an
    array of two bytes)?

    --
    Ian Collins
     
    Ian Collins, Mar 1, 2013
    #7
  8. Stefan Ram Guest

    Ian Collins <> writes:
    >So you propose a "safe" solution that doesn't do what the OP wanted (an
    >array of two bytes)?


    One might return an int value as a kind of array of two char values.
    This should not require memory allocation, but only works where
    sizeof( int )>=2.

    The Java code seems to assume CHAR_BITS==8, which is true in
    Java, but might not be true in C++. A group of 8 bits actually
    is an »octett«, not a »byte«. Even, where sizeof( int )>=2
    is not true, an int should be able to carry two octetts.
     
    Stefan Ram, Mar 1, 2013
    #8
  9. Ian Collins Guest

    Christian Gollwitzer wrote:
    > Am 01.03.13 23:56, schrieb Ian Collins:
    >> Christian Gollwitzer wrote:
    >>> unsigned char getByteFromShort(short x, size_t i) {
    >>> if (i==0) return x & 0xff;
    >>> if (i==1) return (x>>8) & =xff;
    >>> throw std::eek:ut_of_range("Index in short must be 0 or 1");
    >>> }

    >>
    >> So you propose a "safe" solution that doesn't do what the OP wanted (an
    >> array of two bytes)?

    >
    >
    > OK, OK, I changed the topic.
    >
    > typedef std::array<unsigned char,2> twobyte;
    >
    > twobyte getByteFromShort(short x) {
    > twobyte result;
    > result[0]=x & 0xff;
    > result[1]=(x>>8) & 0xff;
    > }
    >
    > Happy? Or does "array" imply "C-style array"?


    Why should it?

    > IMHO translating Java-new to C++-new should be avoided, because in C++
    > RAII is the idiomatic way for memory management, whereas the GC takes
    > care of the array in Java. I think this is worth pointing out to a newbie.
    >
    > BTW, on my machine gcc -O3 translates the above function into "rep;
    > ret", i.e. do nothing.


    Because you didn't return result....

    --
    Ian Collins
     
    Ian Collins, Mar 2, 2013
    #9
  10. writes:

    > how to convert this routine to C++ ?
    >
    > private byte[] getByteFromShort(short x) {
    > byte[] a = new byte[2];
    > a[0] = (byte) (x & 0xff);
    > a[1] = (byte) ((x >> 8) & 0xff);
    > return a;
    > }


    Other answers give you detailed (and important) information about a
    (more or less) literal translation of this code. I'd like to add that I
    would not even write a function for such a simple operation:

    int8_t xbytes [] = { x, x>>8 };

    Of course, whether this is useful depends on what you are going to do
    with the array (which will live on the stack of the "calling" context).
    Dynamic allocation is not cheap, C++ has no garbage collection by
    default, so it's better to avoid putting pressure on the allocator for
    such minuscule pieces of data. If you are going to pass this "array"
    around, you should prefer data structures that carry their own size. But
    are you really going to pass around the two bytes of a short? In actual
    code, I would probably use either x and x>>8, or two distinct variables.

    Note also that 1) I've used int8_t to respect Java's signedness of
    bytes, you could switch to uint8_t to have unsigned bytes; 2) iirc,
    these types are not guaranteed to exist; 3) I didn't bother to zero out
    bits that get truncated later (this applies to your Java code as well,
    where both "&0xff" are absolutely useless), but this is valid only if
    int8_t exists (otherwise, more care is needed, depending on the later
    usage of these "bytes").

    -- Alain.
     
    Alain Ketterlin, Mar 2, 2013
    #10
  11. On 3/2/2013 4:16 AM, Juha Nieminen wrote:
    > Victor Bazarov <> wrote:
    >> [..]
    >> Given that such an attitude is frequent in your posts

    >
    > Frequent? Care to give some examples?


    No. I don't care to continue this particular train of discussion and am
    going to give you the chance to wrap it up since it was you who started it.

    Have a good one!

    V
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Mar 2, 2013
    #11
  12. James Kanze Guest

    On Saturday, 2 March 2013 09:46:21 UTC, Alain Ketterlin wrote:
    > writes:


    > > how to convert this routine to C++ ?


    > > private byte[] getByteFromShort(short x) {
    > > byte[] a = new byte[2];
    > > a[0] = (byte) (x & 0xff);
    > > a[1] = (byte) ((x >> 8) & 0xff);
    > > return a;
    > > }


    > Other answers give you detailed (and important) information about a
    > (more or less) literal translation of this code. I'd like to add that I
    > would not even write a function for such a simple operation:


    > int8_t xbytes [] = { x, x>>8 };


    The advantage of the function is that if you change the format,
    you just have one function to change.

    > Of course, whether this is useful depends on what you are going to do
    > with the array (which will live on the stack of the "calling" context).
    > Dynamic allocation is not cheap, C++ has no garbage collection by
    > default, so it's better to avoid putting pressure on the allocator for
    > such minuscule pieces of data. If you are going to pass this "array"
    > around, you should prefer data structures that carry their own size. But
    > are you really going to pass around the two bytes of a short? In actual
    > code, I would probably use either x and x>>8, or two distinct variables.


    How about a:

    struct BytesForShort
    {
    unsigned char bytes[ sizeof(short) ];
    };

    In most cases, of course, this would be part of a larger set of
    serialization routines, and the output would be via a non-const
    reference argument.

    > Note also that 1) I've used int8_t to respect Java's signedness of
    > bytes, you could switch to uint8_t to have unsigned bytes;


    I think that you'ld almost certainly want an unsigned type.

    > 2) iirc,
    > these types are not guaranteed to exist;


    They are not. But since the starting point was Java, we can
    assume they do. Otherwise, I don't think you could implement
    Java on the machine.

    > 3) I didn't bother to zero out
    > bits that get truncated later (this applies to your Java code as well,
    > where both "&0xff" are absolutely useless), but this is valid only if
    > int8_t exists (otherwise, more care is needed, depending on the later
    > usage of these "bytes").


    I've gotten used to using the `0xFF` to make my intentions
    clear, even if it isn't (usually) necessary. The compiler will
    turn it into a no-op if it isn't necessary.

    --
    James
     
    James Kanze, Mar 5, 2013
    #12
  13. James Kanze Guest

    On Tuesday, March 5, 2013 2:56:15 PM UTC, Juha Nieminen wrote:
    > James Kanze <> wrote:


    > > I've gotten used to using the `0xFF` to make my intentions
    > > clear, even if it isn't (usually) necessary. The compiler will
    > > turn it into a no-op if it isn't necessary.


    > I think you mean that the compiler will remove if it's unnecessary?
    > Because a 'nop' is an actual opcode that takes a clock cycle (or such)
    > to execute, and would be useless baggage.


    I wasn't thinking in terms of machine instructions, so much as
    the more general meaning: no-op means "no operation", in other
    words, do nothing. In particular, when I write something like:
    "i & 0xFF", where i is an `int` in memory, all of the
    compilers I know will simply generate a byte access for the low
    order byte, with no and instruction; similarly, for "(i >> 8)
    & 0xFF" or "(i & 0xFF00) >> 8" (although I'm not sure about the
    latter---I tend to write the former, and I've only really looked
    at generated code for code I've written).

    --
    James
     
    James Kanze, Mar 6, 2013
    #13
  14. Jorgen Grahn Guest

    On Thu, 2013-02-28, wrote:
    > Sorry for this stupid question by I am very new to C++
    >
    > how to convert this routine to C++ ?
    >
    > private byte[] getByteFromShort(short x) {
    > byte[] a = new byte[2];
    > a[0] = (byte) (x & 0xff);
    > a[1] = (byte) ((x >> 8) & 0xff);
    > return a;
    > }
    >
    > Thank you.


    Since the responses soon made it clear that the interface design is
    the problem, here's how I usually do it:

    namespace bigendian {

    uint8_t* put16(uint8_t* p, unsigned val);
    void put16(uint8_t*& p, unsigned val);
    }

    - Assumes your "shorts" are really unsigned.

    - Either updates the buffer pointer or returns a new one;
    feel free to pick one. I find that it's best to let the
    function reveal this information, even if we know that
    exactly two bytes will be used.

    - A template which uses output iterators is more useful.

    - This is a simple case of serialisation -- representing
    C++ objects as octet arrays. There are people who do
    this a lot and do elaborate things; I am not one of them.
    I just do things like building IPv4 headers.

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
     
    Jorgen Grahn, Mar 9, 2013
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kirby
    Replies:
    3
    Views:
    678
    Kirby
    Oct 8, 2004
  2. carmen
    Replies:
    4
    Views:
    30,811
    ersecchio
    Jan 12, 2010
  3. Shane Wealti

    convert byte[] to Byte[]

    Shane Wealti, Jun 13, 2005, in forum: Java
    Replies:
    5
    Views:
    42,573
    Brzezi
    Jun 13, 2005
  4. Replies:
    20
    Views:
    9,941
    licebmi
    Sep 7, 2009
  5. Polaris431
    Replies:
    8
    Views:
    795
    SM Ryan
    Dec 4, 2006
Loading...

Share This Page