Funny bit games

Discussion in 'C++' started by Isliguezze, Jun 24, 2008.

  1. Isliguezze

    Isliguezze Guest

    Hi. There's a task of splitting an int into three unsigned char's.
    There's also one limitation. The maximum size of the given int is
    10^9, what's enough to code with as small as 17 bits. So, what is the
    problem? How to split a maximum 17 value bits containing int into 3
    unsigned chars(8+8+1, 6 bits)? The problem is that I can't use
    unsigned char pointer, to point on int like this:

    unsigned char *uchp;
    unsigned int i = 1000000000;

    uchp = &i;

    for (int j = 0; j < sizeof(int); ++j)
    cout << *uchp;

    to point on each byte of int... What can be performed in assembler
    using BYTE PTR, architecture is Intel x86. But how to split int into
    three unsigned chars using C++?
    Isliguezze, Jun 24, 2008
    #1
    1. Advertising

  2. Isliguezze

    Isliguezze Guest

    > See the bitwise operator AND (&) and the right shift operator (>>).
    > Apply the mask, then shift.


    What do I need the mask for? What is mask? How is it constructed?
    Isliguezze, Jun 24, 2008
    #2
    1. Advertising

  3. Isliguezze

    R.A. Nagy Guest

    "Isliguezze" <> wrote in message
    news:...
    > Hi. There's a task of splitting an int into three unsigned char's.
    > There's also one limitation. The maximum size of the given int is
    > 10^9, what's enough to code with as small as 17 bits. So, what is the
    > problem? How to split a maximum 17 value bits containing int into 3
    > unsigned chars(8+8+1, 6 bits)? The problem is that I can't use
    > unsigned char pointer, to point on int like this:
    >
    > unsigned char *uchp;
    > unsigned int i = 1000000000;
    >
    > uchp = &i;
    >
    > for (int j = 0; j < sizeof(int); ++j)
    > cout << *uchp;
    >
    > to point on each byte of int... What can be performed in assembler
    > using BYTE PTR, architecture is Intel x86. But how to split int into
    > three unsigned chars using C++?


    While this is not the same as what you are discussing, packing / unpacking 8
    bits using a union can come in handy from time to time:

    -----

    #include <iostream>

    using namespace std;

    void main(int argc, char *argv[])
    {
    typedef int XINT;
    typedef char XBYTES[4];

    union sigma
    {
    XINT xint;
    XBYTES xbytes;
    } test;

    test.xint = 'ABCD';
    cout << test.xbytes[0] << endl;
    cout << test.xbytes[1] << endl;
    cout << test.xbytes[2] << endl;
    cout << test.xbytes[3] << endl;
    }

    -----

    IMO far too few is the opportunity to discuss the virture of unions. While
    we are not framing more than 8 bits (as requested), the technique is one for
    a few new-of-us to be aware of. (i.e. 'funny bit games' :)

    R.A. Nagy
    http://www.Soft9000.com
    R.A. Nagy, Jun 24, 2008
    #3
  4. Isliguezze

    R.A. Nagy Guest

    "Isliguezze" <> wrote in message
    news:...
    >> See the bitwise operator AND (&) and the right shift operator (>>).
    >> Apply the mask, then shift.

    >
    > What do I need the mask for? What is mask? How is it constructed?


    Here is an adequate place to start:

    http://en.wikipedia.org/wiki/Mask_(computing)
    R.A. Nagy, Jun 24, 2008
    #4
  5. Isliguezze

    R.A. Nagy Guest

    R.A. Nagy, Jun 24, 2008
    #5
  6. Isliguezze

    R.A. Nagy Guest

    Oh, you are so right - But I though we were talking about Intel here? A
    defined architecture?

    I also believe that I mentioned that this was not in keeping with what the
    original questions was ...??

    But either way Victor, thank you for the correction. I am humbled by your
    tact, humility, and overall demeanor.

    YOU ARE THE MAN!!

    ;-)




    "Victor Bazarov" <> wrote in message
    news:g3r99e$93q$...
    > R.A. Nagy wrote:
    >> [..]
    >> While this is not the same as what you are discussing, packing /
    >> unpacking 8 bits using a union can come in handy from time to time:
    >>
    >> -----
    >>
    >> #include <iostream>
    >>
    >> using namespace std;
    >>
    >> void main(int argc, char *argv[])

    >
    > Try to make it 'int main'. Teaching 'void main' is just wrong. Now, do
    > you use 'argc' and 'argv'? If not, why declare them? So, consider
    >
    > int main()
    >
    >> {
    >> typedef int XINT;
    >> typedef char XBYTES[4];
    >>
    >> union sigma
    >> {
    >> XINT xint;
    >> XBYTES xbytes;
    >> } test;
    >>
    >> test.xint = 'ABCD';
    >> cout << test.xbytes[0] << endl;
    >> cout << test.xbytes[1] << endl;
    >> cout << test.xbytes[2] << endl;
    >> cout << test.xbytes[3] << endl;
    >> }
    >>
    >> -----
    >>
    >> IMO far too few is the opportunity to discuss the virture of unions.

    >
    > Virtue? What you do here has undefined behaviour. Use of the union is
    > only defined if you access the same value you stored.
    >
    > > While
    >> we are not framing more than 8 bits (as requested), the technique is one
    >> for a few new-of-us to be aware of. (i.e. 'funny bit games' :)

    >
    > This is not a technique. It's a hack. Besides, it relies on the 'int' to
    > have the size of 4 char which isn't necessarily so. Also, the OP asked
    > for "unsigned char"...
    >
    > V
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask
    R.A. Nagy, Jun 24, 2008
    #6
  7. Isliguezze

    Isliguezze Guest

    Nice hack actually, bu I don't think that I do really understand this
    string:

    > test.xint = 'ABCD';


    What does it do? I need to convert 17 bit int to three unsigned chars
    in such way to have it all look like this: 8 bits + 8 bits + 1 bit,
    and how to restore them back to an int? I didn't hear proper answer,
    how do I do that in C++?
    Isliguezze, Jun 25, 2008
    #7
  8. Isliguezze

    Mirco Wahab Guest

    Isliguezze wrote:
    > Nice hack actually, bu I don't think that I do really understand this
    > string:
    >
    >> test.xint = 'ABCD';

    >
    > What does it do? I need to convert 17 bit int to three unsigned chars
    > in such way to have it all look like this: 8 bits + 8 bits + 1 bit,
    > and how to restore them back to an int? I didn't hear proper answer,
    > how do I do that in C++?


    I didn't understand what this is good for and
    what constraints are given (range, speed, purpose).

    If it's only to prove a pint, you could do it w/
    bitset and regex, with no shifting/masking at all:



    #include <bitset>
    #include <string>
    #include <iostream>
    #include <boost/regex.hpp>

    int main()
    {
    unsigned long uch[3];
    unsigned int i = 2;
    using namespace std;

    string s = bitset<17>(i).to_string();
    boost::smatch m;

    if(boost::regex_match(s, m, boost::regex("^(.{8})(.{8})(.{1})$"))) {
    uch[0] = ( bitset<8>(m[1].str()) ).to_ulong();
    uch[1] = ( bitset<8>(m[2].str()) ).to_ulong();
    uch[2] = ( bitset<1>(m[3].str()) ).to_ulong();
    }
    cout << "number: " << i << ", bitmap: " << s << endl
    << "8 bit, value: " << uch[0] << endl
    << "8 bit, value: " << uch[1] << endl
    << "1 bit, value: " << uch[2] << endl;

    return 0;
    }


    Regards

    M.
    Mirco Wahab, Jun 25, 2008
    #8
  9. Isliguezze wrote:
    > I need to convert 17 bit int to three unsigned chars
    > in such way to have it all look like this: 8 bits + 8 bits + 1 bit,
    > and how to restore them back to an int? I didn't hear proper answer,
    > how do I do that in C++?


    You already got a link to wikipedia, where you can find what you need.

    But just to get the idea, maybe you want something like (untested, and
    perhaps the casts are not necessary):

    uint8_t lowest, higher, evenHigher
    unsigned int num = <the integer to convert>

    low = static_cast<uint8_t>(num & 0xff);
    higher = static_cast<uint8_t>((num & 0xff00) >> 8);
    evenHigher = static_cast<uint8_t>((num & 10000) >> 16);


    And the reverse:

    unsigned int num2 = (static_cast<unsigned int>(evenHigher) << 16) |
    (static_cast<unsigned int>(higher) << 8) |
    lowest;


    hth,
    Michael
    Michael Oswald, Jun 25, 2008
    #9
  10. Isliguezze

    James Kanze Guest

    On Jun 25, 4:28 pm, Isliguezze <> wrote:
    > Nice hack actually, bu I don't think that I do really understand this
    > string:


    > > test.xint = 'ABCD';


    > What does it do?


    Whatever the implementation wants it to do. You'll have to look
    up the documentation of your implementation to find out.

    In general, multibyte character literals are a misfeature, still
    supported for reasons of backward compatibility, but not
    something anyone should use, or even worry about understanding.

    > I need to convert 17 bit int to three unsigned chars
    > in such way to have it all look like this: 8 bits + 8 bits + 1 bit,
    > and how to restore them back to an int? I didn't hear proper answer,
    > how do I do that in C++?


    Someone did mention shifting and the bitwise operators, it
    seems. But you've not really specified enough: which bits
    belong in what character. If I suppose network byte order, and
    put the bit 16 (the high order bit) in the first byte, the
    correct answer would be something like:

    void
    to3Bytes( unsigned char* dest, int value )
    {
    assert( value >= 0 && value < (1 << 17 ) ) ;
    dest[ 0 ] = (value >> 16) & 0xFF ;
    dest[ 1 ] = (value >> 8) & 0xFF ;
    dest[ 2 ] = (value ) & 0xFF ;
    }

    int
    from3Bytes( unsigned char* source )
    {
    return dest[ 0 ] << 16
    | dest[ 1 ] << 8
    | dest[ 2 ] ;
    }

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jun 25, 2008
    #10
  11. Isliguezze

    R.A. Nagy Guest

    "Isliguezze" <> wrote in message
    news:...
    > Nice hack actually, bu I don't think that I do really understand this
    > string:
    >
    >> test.xint = 'ABCD';

    >
    > What does it do? I need to convert 17 bit int to three unsigned chars
    > in such way to have it all look like this: 8 bits + 8 bits + 1 bit,
    > and how to restore them back to an int? I didn't hear proper answer,
    > how do I do that in C++?


    The code just assigns a bit pattern to whatever the architecture defines as
    an int. The example had nothing to do with your 8 + 8 + 1 problem. Sorry.

    Also understand that, be they signed or unsigned, that characters typically
    have the same number of bits. (I was surprised to ready of your problem.
    Does not happen too offend!)

    FWIW, consider running the snippet on Intel 32 - Notice how it actually
    prints the characters backward - loosely reflects the underlying
    architecture of the processor (little-endian.)

    I was just a fun fact - er ... hack - Motorola would do something else. One
    of the reasons why bit shifting / masking is a superior solution for your
    particular problem. Also the reason for the irritated comments.

    ..02 ends.
    R.A. Nagy, Jun 25, 2008
    #11
  12. Isliguezze

    James Kanze Guest

    On Jun 25, 7:31 pm, Victor Bazarov <> wrote:
    > James Kanze wrote:
    > > [..]


    > > int
    > > from3Bytes( unsigned char* source )


    > int
    > from3Bytes(unsigned char const* source) // 'const' just in case...


    Yes. And not just in case; you want to be able to call the
    function (without a const cast) from another function which
    received the buffer as const.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jun 26, 2008
    #12
    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. Delaney, Timothy C (Timothy)

    RE: Python in Games (was RE: [Stackless] Python in Games)

    Delaney, Timothy C (Timothy), Jun 14, 2005, in forum: Python
    Replies:
    3
    Views:
    282
  2. Replies:
    3
    Views:
    1,743
    Timothy Bendfelt
    Jan 19, 2007
  3. Replies:
    9
    Views:
    966
    Juha Nieminen
    Aug 22, 2007
  4. Nikos
    Replies:
    11
    Views:
    497
    Mark Clements
    Apr 28, 2005
  5. Jeff.M
    Replies:
    6
    Views:
    171
    Lasse Reichstein Nielsen
    May 4, 2009
Loading...

Share This Page