Thread: int into bits Bitwise

  1. #1
    Registered User
    Join Date
    May 2010
    Posts
    2

    int into bits Bitwise

    Hello i've been given the task of breaking an integer into bits (packing) to be sent across a network then unpacked. I can do the send code i'm just struggling to see how you break something into an int value as i dont understand the bit process we were given a 20 minutes presentation and are now expected to complete it s.any help would be great

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    I hope you took some notes so you can provide some clarification here. Are you sure you mean "bits" and not "bytes"?

    Ints are already packed for purposes such as "sending them across a network". Perhaps what you are looking for has something to do with endianess? Network byte order is an (atavistic) big endian norm, whereas most computers are little endian.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User
    Join Date
    May 2010
    Posts
    2
    sorry im not being clear the task says

    use the individual bits of the two integers transmit the state across to the client (the ints they hold the game state x's and 0's)

    its not very clear how its been written but we were told to use bitwise to send them as its smaller i guess its just to see how small they can be

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Hmmm. Well, it is not really advantageous to say try and compress an int to make a transmission smaller since it requires processor time at both ends.

    If the int is a bitfield, the individual bits are used as flags, however, you don't need to do anything to it, you can just transmit it as is -- an int is (normally) 4 bytes which is 32 bits. You don't have to create or extract them. The handling of each bit in the bitfield is done by the client.

    Is that what this is about? Creating and using bitflags/bitfields?
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    Registered User
    Join Date
    May 2010
    Posts
    21
    sorry had to make a new account mine doesn't work for some reason.

    The purpose it just to show it can be done. Basically its a network game of 0 and X's with a 3x3 grid. the server and client take turns, each time its stored in an ai or a player int then sent, the assignment just asks us to derive from the existing class then in the send function we transmit the individual bits in the 2 ints. The purpose is to make it smaller as an example of what can be done. However the presentation was damn awful and no one understood how to do it as the presentation didnt work when we coded it.

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by bdillion View Post
    The purpose it just to show it can be done. Basically its a network game of 0 and X's with a 3x3 grid. the server and client take turns, each time its stored in an ai or a player int then sent, the assignment just asks us to derive from the existing class then in the send function we transmit the individual bits in the 2 ints. The purpose is to make it smaller as an example of what can be done.
    Right, that is a use for bitflags. So this is about a bitfield. However, you don't have to translate the ints into anything in order to do this, or transmit them as anything other than ints. The idea is this (let's use a single byte instead of 4 for simplicity):

    00000000

    One byte, eight bits. Each one can be either 1 or 0. So you can store boolean values this way. Let's pretend it is a 2x2 grid, and assign two bits to each square, since we need more than two possibilites (X, O, and empty). So 00 would be empty, 01 (ie, 1 in decimal) would be X, 10 (2 in decimal) would be O.

    That's an OR mask, which you have probably used before with standard library functions:
    Code:
    #define SQUARE_ISX 1
    #define SQUARE_ISO 2
    You can set and test with a mask:
    Code:
    board |= SQUARE_ISX;   // set
    if (board & SQUARE_ISX)  //test with AND
    Here, "board" would be the int. Of course, you want more than one square per board. To do that, you have two choices:

    - use #defines for each square eg, #define SQUARE2_ISX 4, (0100) This method might be easier and is in fact more efficient, I think. Just remember, each flag needs to be a power of 2 (1, 2, 4, 8, 16, etc) or else your flags will interfere with each other's bits.
    - bitshift thru the int for each square.

    For more info google "bitshifting", "bit fields", and "bitwise", cause bit wise is what you have to be here
    Last edited by MK27; 05-18-2010 at 04:22 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Registered User
    Join Date
    May 2010
    Posts
    21
    i've set it and the board is in an array called board

    #define SQUARE_NULL 0
    #define SQUARE_X 1
    #define SQUARE_O 2

    then tested it

    board[1] |= SQUARE_X;
    if (board[1] &= SQUARE_X)

    but im not sure what it suppose to be testing because its not checking where on the board x is when the first place on the board is filled with an o it doesnt check its an o it just checks its full. I really not to sure on this part


    I also tried

    data->playerData = SQUARE_X;
    data->aiData = SQUARE_O;

    if(board[1] = SQUARE_O)
    cout << "ai here";

    however it says the ai is playing everyturn
    Last edited by bdillion; 05-18-2010 at 01:37 PM.

  8. #8
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by MK27 View Post
    if (board &= SQUARE_ISX) //test with AND
    Typo correction:

    Code:
    if (board & SQUARE_ISX)  //test with AND
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  9. #9
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by bdillion View Post
    i've set it and the board is in an array called board

    #define SQUARE_NULL 0
    #define SQUARE_X 1
    #define SQUARE_O 2

    then tested it

    board[1] |= SQUARE_X;
    if (board[1] &= SQUARE_X)

    but im not sure what it suppose to be testing because its not checking where on the board x is when the first place on the board is filled with an o it doesnt check its an o it just checks its full. I really not to sure on this part
    Post the entire program, if possible.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  10. #10
    Registered User
    Join Date
    May 2010
    Posts
    21
    i'm working in server but have added both server and client so u can see whats happening the only class i can change is the main and dirvied class in server otherwise i would try changing the way the code works

    this is the code

    file.rar

  11. #11
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by bdillion View Post
    i'm working in server but have added both server and client so u can see whats happening the only class i can change is the main and dirvied class in server otherwise i would try changing the way the code works

    this is the code

    file.rar
    No, I mean post the actual code (using code tags) here. Also:

    Code:
    if(board[1] = SQUARE_O)
    ...you're assigning a value there (not to mention that an equality test isn't what you want, anyway)...
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  12. #12
    Registered User
    Join Date
    May 2010
    Posts
    21
    Code:
    #include "stdafx.h"
    #include <stdio.h>
    #include <winsock2.h>
    #include <ws2tcpip.h>
    #include <iostream>
    #include <ctime> 
    #include <math.h>
    #include <iostream>
    #include <vector>
    //#define bitwise
    using namespace std;
    
    
    
    // Noughts and Crosses (Tic Tack Toe) game
    class NoughtsAndCrosses{
    protected:
    	// 3 by 3 board is represented as a one dimensional array
    	char board[9];
    	// Players symbols are either X or O
    	char playerSymbol;
    	char aiSymbol;
    	// Game state
    	bool playerWin,aiWin,draw;
    	// If there is a winner or a draw update the state
    	bool CheckWin(char symbol){	
    		bool won = false;
    		// Is there a winner?
    		// Check horizontal 
    		if (board[0] == symbol && board[1] == symbol && board[2] == symbol) won = true;
    		if (board[3] == symbol && board[4] == symbol && board[5] == symbol) won =  true;
    		if (board[6] == symbol && board[7] == symbol && board[8] == symbol) won =  true;
    		// Check vertical
    		if (board[0] == symbol && board[3] == symbol && board[6] == symbol) won =  true;
    		if (board[1] == symbol && board[4] == symbol && board[7] == symbol) won =  true;
    		if (board[2] == symbol && board[5] == symbol && board[8] == symbol) won =  true;
    		// Check diagonals
    		if (board[0] == symbol && board[4] == symbol && board[8] == symbol) won =  true;
    		if (board[2] == symbol && board[4] == symbol && board[6] == symbol) won =  true;
    		// If there is a winner who won?
    		if (won){
    			if (symbol == aiSymbol) aiWin = true;
    			else playerWin = true;
    			return true;
    		}
    		// If no one has won then check to see if it is a draw
    		for(int n=0;n<9;n++)
    			if (board[n] == ' ') return false;
    		draw = true;
    		return true;
    	}
    public:
    	NoughtsAndCrosses(){
    		for(int n=0;n<9;n++)
    			board[n] = ' ';
    		playerSymbol = 'X';
    		aiSymbol = 'O';
    		playerWin = aiWin  = draw = false;
    	}
    	bool IsFinished(){
    		if (playerWin || aiWin || draw) return true;
    		else return false;
    	}
    	void DisplayWinner(){
    		if (playerWin)
    			cout << "\n The Player has won \n";
    		else if (aiWin)
    			cout << "\n The AI has won \n";
    		else
    			cout << "\n Its a draw \n";
    	}
    	bool Play(char symbol, int pos){
    		// Ensure the position is free
    		if(board[pos]== ' '){
    			board[pos] = symbol;
    			CheckWin(symbol);
    			return true;
    		}
    		else return false;
    	}
    	void AIPlay(){
    		srand((unsigned)time(0));
    		int index;
    		do{
    			index = rand();
    			index = index % 9;
    		}
    		while(! Play('O', index));
    	}
    	void Dump(){
    		cout << board[0] << " | " << board[1] << " | " << board[2] << "\n";
    		cout << "--------\n";
    		cout << board[3] << " | " << board[4] << " | " << board[5] << "\n";
    		cout << "--------\n";
    		cout << board[6] << " | " << board[7] << " | " << board[8] << "\n";
    	}
    	// Transmit the whole object to the opponent
    	void Send(SOCKET s)
    	{
        char newarray[sizeof(NoughtsAndCrosses)];
    	memcpy( newarray, this, sizeof(NoughtsAndCrosses));
    	int sendCount = send(s, newarray,sizeof(NoughtsAndCrosses), 0);
    	}
    };
    
    
    // Contains game data to be transmitted
    struct GameData{
    	int playerData,aiData;//player =x ai = 0
    };
    
    
    
    class bitwiseNoughtsAndCrosses:NoughtsAndCrosses
    {
    #define SQUARE_NULL 0
    #define SQUARE_X 1
    #define SQUARE_O 2
    
    	
    /*#define SQUARE2_X 4
    #define SQUARE2_O 8
    #define SQUARE3_X 16
    #define SQUARE3_O 32
    #define SQUARE4_X 64
    #define SQUARE4_O 128
    #define SQUARE5_X 252
    #define SQUARE5_O 516
    #define SQUARE6_X 1032
    #define SQUARE6_O 2064
    #define SQUARE7_X 1
    #define SQUARE7_O 2
    #define SQUARE8_X 1
    #define SQUARE8_O 2
    #define SQUARE9_X 1
    #define SQUARE9_O 2
    */
    public:
    	
    vector<unsigned char> bits;
        unsigned int totalBits, totalBytes;
    	void NoughtsAndCrosses(unsigned int size)
        {
       
        }
    	void Packing()
    	{
    
    	GameData *data = new GameData();
    	data->playerData = SQUARE_X;
    	data->aiData = SQUARE_O;
    
    	if(board[1] = SQUARE_O)
    	cout << "ai here";
    	
    
    	
    	}
        void Send(SOCKET s)
    	{
        
    	}
        void Unpacking()
        {
        }
    
    };

  13. #13
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Sebastiani View Post
    Typo correction:
    Yo whoops! Bad one.

    Also, in fact SQUARE_EMPTY is not necessary, I deleted that earlier from the post. Anyway, here's a demo that may clarify how this works for you. Notice the bitshifting in the defines, which makes it somewhat easier. I shift by two each time because we use two bits for each square:

    Code:
    #include <iostream>
    
    #define SQUARE0_X 1
    #define SQUARE0_O 2
    #define SQUARE1_X 1 << 2
    #define SQUARE1_O 2 << 2
    #define SQUARE2_X 1 << 4
    #define SQUARE2_O 2 << 4
    #define SQUARE3_X 1 << 6
    #define SQUARE3_O 2 << 6
    
    class Bitfield {
    	int field;
    	public:
    		Bitfield () { };
    		bool check (int flag) {
    			if (field & flag) return true;
    			return false;
    		}
    		void set (int flag) {
    			field |= flag;
    		}
    		void unset (int flag) {
    			field ^= flag;
    		}
    		~Bitfield() { };
    };
    
    using namespace std;
    
    int main(int argc, const char *argv[]) {
    	Bitfield example;
    
    	example.set(SQUARE1_O);
    	example.set(SQUARE2_X);
    
    	if (example.check(SQUARE1_X)) cout << "S1 is X\n";
    	else if (example.check(SQUARE1_O)) cout << "S1 is O\n";
    	else cout << "S1 is empty\n";
    
    	if (example.check(SQUARE2_X)) cout << "S2 is X\n";
    	else if (example.check(SQUARE2_O)) cout << "S2 is O\n";
    	else cout << "S2 is empty\n";
    
    	if (example.check(SQUARE3_X)) cout << "S3 is X\n";
    	else if (example.check(SQUARE3_O)) cout << "S3 is O\n";
    	else cout << "S3 is empty\n";
    
    	example.unset(SQUARE2_X);
    	cout << "\nNow:\n";
    
    	if (example.check(SQUARE2_X)) cout << "S2 is X\n";
    	else if (example.check(SQUARE2_O)) cout << "S2 is O\n";
    	else cout << "S2 is empty\n";
    
    	return 0;
    }
    You can obviously tailor this somewhat to set X or O within the functions, etc, so you don't have to use the flags in the method calls.
    Last edited by MK27; 05-18-2010 at 02:28 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  14. #14
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Code:
    	void Send(SOCKET s)
    	{
        char newarray[sizeof(NoughtsAndCrosses)];
    	memcpy( newarray, this, sizeof(NoughtsAndCrosses));
    	int sendCount = send(s, newarray,sizeof(NoughtsAndCrosses), 0);
    	}
    Why are you copying the data to a new buffer (rather than just sending "NoughtsAndCrosses" itself)? Also, the function should be virtual, as it needs to be overridden by derived classes.

    Code:
    #define SQUARE_NULL 0
    #define SQUARE_X 1
    #define SQUARE_O 2
    
    	
    /*#define SQUARE2_X 4
    #define SQUARE2_O 8
    #define SQUARE3_X 16
    #define SQUARE3_O 32
    #define SQUARE4_X 64
    #define SQUARE4_O 128
    #define SQUARE5_X 252
    #define SQUARE5_O 516
    #define SQUARE6_X 1032
    #define SQUARE6_O 2064
    #define SQUARE7_X 1
    #define SQUARE7_O 2
    #define SQUARE8_X 1
    #define SQUARE8_O 2
    #define SQUARE9_X 1
    #define SQUARE9_O 2
    Using defines like this isn't considered a good practice (macro "pollution"). Use enums, eg:

    Code:
    enum
    {	
    	ABC = 12, 
    	XYZ = 13
    };
    Also, as already mentioned, your bitmasks should be powers of two, and shouldn't overlap with eachother.

    Code:
    	void Packing()
    	{
    
    	GameData *data = new GameData();
    	data->playerData = SQUARE_X;
    	data->aiData = SQUARE_O;
    
    	if(board[1] = SQUARE_O)
    	cout << "ai here";	
    	}
    Why are you even using "new" (not to mention that there is no corresponding "delete")? Just declare a local variable. At any rate, it isn't really clear what you're trying to do here. Moreover, if you are packing the board state into an integer, how are you to mark cells that aren't yet filled (eg, you need 3 states: X, O, and UNDEFINED (not set))?
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  15. #15
    Registered User
    Join Date
    May 2010
    Posts
    21
    nothing but the derived class can be changed the other functions and classes above are prewritten for us

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. NEED HELP READING FILE and PRINTING
    By geoffr0 in forum C Programming
    Replies: 4
    Last Post: 04-16-2009, 05:26 PM
  2. memory leak
    By aruna1 in forum C++ Programming
    Replies: 3
    Last Post: 08-17-2008, 10:28 PM
  3. Replies: 26
    Last Post: 11-30-2007, 03:51 AM
  4. newbie needs help with code
    By compudude86 in forum C Programming
    Replies: 6
    Last Post: 07-23-2006, 08:54 PM
  5. getting a headache
    By sreetvert83 in forum C++ Programming
    Replies: 41
    Last Post: 09-30-2005, 05:20 AM