SA-MP Forums

Go Back   SA-MP Forums > SA-MP Scripting and Plugins > Scripting Help > Tutorials

Reply
 
Thread Tools Display Modes
Old 18/09/2010, 11:50 AM   #1
Kyosaur
Gangsta
 
Kyosaur's Avatar
 
Join Date: Mar 2008
Location: USA - California
Posts: 973
Reputation: 349
Lightbulb An in-depth look at binary and binary operators.

Navigation
  • Binary
    • What is binary
    • A deeper look at bits
      • Signed integers
      • Unsigned integers
    • Binary operators
      • Bitwise AND
      • Bitwise OR
      • Bitwise XOR
      • Bitwise NOT
      • Bit Shifting
        • Arithmetic shifts
          • Right shift
          • Left shift
        • Logical Shifts
          • Right shift
          • Left shift


What is binary?

Binary is a numeral system that uses two unique symbols to represent numbers. While the more common decimal system uses ten numerals (base 10), binary uses only 0 and 1. This may sound useless in every day life, but binary is essential when it comes to computers. Computers at their lowest level perform all of their calculations by manipulating the flow of electricity to indicate on and off states. This is exactly what binary is, just a ton of switches flipped on and off. This is a sort of alien concept to most people, so lets take a look at the decimal and binary system next to each other.


Decimal (base 10)
pawn Code:
0
1
2
3
4
5
6
7
8
9
10
11
12
13

Binary (Base 2)
pawn Code:
0 //0
1 //1
10 //2
11 //3
100 //4
101 //5
110 //6
111 //7
1000 //8
1001 //9
1010 //10
1011 //11
1100 //12
1101 //13

Looking at both systems beside one another, you'll notice they behave exactly the same. Once you reach the last available number you have to move on to another place. These places in binary are referred to as bits (binary digits) and are simply powers of two; just as places in the decimal system are powers of 10. To prove this, lets take a look at the number 13 in standard notation.


NOTE: '^' is power in these next few examples, not bitwise exclusive (which we'll cover later.


Decimal (base 10)
pawn Code:
13

//which equals

1 * (10^1) + 3 * (10^0)

//which equals

10+3

//which equals

13

Binary (base 2)
pawn Code:
1101

//which equals

1 * (2^3) + 1 * (2^2) + 0 * (2^1) + 1 * (2^0)

//which equals

8+4+0+1

//which equals

13

We can see from the preceding example that if a bit is set to 0, we can ignore it and move on; after all, anything multiplied by 0 is going to be 0. The previous example was a little over complicated and was just me trying to being absolutely clear. When you're converting from binary, all you really have to worry about is adding up the powers of all the bits that are turned on.

Here are 12 powers of 2 just off the top of my head:

pawn Code:
4096,2048,1024,512,256,128,64,32,16,8,4,2,1

If you know nothing about working with powers, this probably makes no sense to you at all. A power is a number multiplied by itself x amount of times. With this information in mind, the preceding list of powers probably makes more sense; well with the exception of 1. You may be curious why 2 raised to the power of 0 gives a result of 1, all i can say to this is that it just does.

pawn Code:
2^1 = 2, 2^3 = 4, 2^4 = 8

We can see that when we move to the right, our previous value is multiplied by 2; so its safe to assume that when we move to the left our new value is just the previous number divided by 2. With this in mind you can see how we can end up with 2 to the zeroth power equaling 1. If this isn't satisfying enough, im sure you can find more proof on ******. All that being said, lets take a look at one final example, and lets make it somewhat complicated!

pawn Code:
111011001011111000 //242424

//Remember, ignore the bits that arent turned on.

1 * (2^17) = 131072

1 * (2^16) = 65536

1 * (2^15) = 32768

1 * (2^13) = 8192

1 * (2^12) = 4096

1 * (2^9) = 512

1 * (2^7) = 128

1 * (2^6) = 64

1 * (2^5) = 32

1 * (2^4) = 16

1 * (2^3) = 8


131072+65536+32768+8192+4096+512+128+64+32+16+8
=
242424

Remember when converting: The first power is 0 so dont make the mistake as seeing the 18th place as 2^18. There are indeed 18 powers, but that is including the power of 0, so 17 is actually our highest power.



A deeper look at bits

Most programming languages allow different data types which range in the amount of bits that can be used to store information; however pawn is a typeless 32 bit language. This means that pawn will always have 32 bits available for storing information. So what happens when you have to much information? The answer to that question lies with signed and unsigned integers.
  • Signed integers

    Have you ever noticed that when an integer in pawn gets to high it turns into a negative? This "wrapping" is due to you go OVER the maximum value in pawn which is:

    pawn Code:
    2^31 - 1 //Power, not bitwise exclusive. Also the -1 is because we count 0 (there ARE 2,147,483,648 values, but that is with 0, So technically 2,147,483,647 is the max).

    //which equals

    2,147,483,647

    //which in binary is

    1111111111111111111111111111111 //31 bits- all on

    You might be wondering why THAT is the max value, and not 2^32-1 (4,294,967,295). This is where signed and unsigned integers come into play. Signed integers have the ability to store negative values, where unsigned integers do not. This might sound like im straying away from the question, but i assure you i am not. The reason the maximum integer isnt 2^32-1 is because the 32nd bit is used as a sort of toggle for negative and positive values. This is called the MSB (Most significant bit) if the MSB is turned on, the number will be negative; if its turned off, the number is positive. Pretty simple, right?

    Before i show a few negative values, i need to explain how negative values are represented in pawn. Pawn uses a system called 2's complement to represent negative values, which basically means you flip every single bit in your number and add 1 to the new number in order to make it negative.

    Lets take a look at a few negative values while this idea is still in your head:

    pawn Code:
    11111111111111111111111111111111 //all 32 bits turned on

    //equals

    -1

    //and

    11111111111111111111111111111110

    //equals

    -2

    //and finally

    10000000000000000000000000000000

    //equals

    -2147483648

    See, all negative numbers are simply the original positive number with all its bits flipped and increased by one. This is super clear with our last example, as the highest POSITIVE integer is 2147483647.

    From this we can see that the number range in pawn is actually:

    pawn Code:
    −2^31 to +2^31 − 1
  • Unsigned integers

    There is no such thing as unsigned integers in pawn, but im adding this just so its balanced. The only difference between a signed integer and an unsigned integer is that unsigned integers can not store negative values; Integers still wrap around, but they wrap back to 0, instead of a negative value.


Binary operators

Binary operators allow you to manipulate individual bits of a bit pattern. Lets take a look at a list of available bitwise operators.

  • Bitwise arithmetic shift: >>, and <<
  • Bitwise logical shift: >>>
  • Bitwise NOT (aka complement): ~
  • Bitwise AND: &
  • Bitwise OR: |
  • Bitwise XOR (aka exclusive-or): ^

  • Bitwise AND


    NOTE: Not to be confused by the logical AND operator '&&'


    A binary AND simply takes the logical AND of the bits in each position of a number in binary form. This sounds a bit confusing, so lets take a look at it in action!

    pawn Code:
    1100 //12
    &
    0100 //4
    =
    0100 //4 as they both have "100" in them (which is 4)

    That was a little easy, lets take a look at a harder one:

    pawn Code:
    10111000 //184
    &
    01001000 //72
    =
    00001000 //8

    Looking at the examples should give you a pretty good idea what this operator does. It compares two bit sets together, if both of them share a bit of 1, the result will have the same bit turned on. If they share no bits at all, then the result is 0.
  • Bitwise OR


    NOTE: Not to be confused by the logical OR operator '||'


    Bitwise OR works almost exactly the same as bitwise AND. The only difference between the two is that bitwise OR only needs one of the two bit patterns to have a bit turned on in order for the result to have the same bit turned on. Lets take a look at a couple of examples!

    pawn Code:
    1100 //12
    |
    0100 //4
    =
    1100 //12.

    Lets take a look at one more example.

    pawn Code:
    10111000 //184
    |
    01001000 //72
    =
    11111000 //248

    I think this is pretty self explanatory, if either of the numbers have a bit turned on the resulting number will also have that bit turned on.
  • Bitwise XOR

    This operator is a little similar to the bitwise OR operator, but there is a bit of a difference. Lets look at the same example used in the bitwise OR section, and see if you can spot the difference.

    pawn Code:
    1100 //12
    ^
    0100 //4
    =
    1000 //8.

    and finally:

    pawn Code:
    10111000 //184
    ^
    01001000 //72
    =
    11110000 //240

    The only difference between bitwise XOR and bitwise OR, is that if both bit patterns have the same bit turned on, then the result will not have that bit turned on.
  • Bitwise NOT

    This operator flips every bit in the bit pattern, turning all 1's to 0's and vise versa.

    pawn Code:
    ~0
    =
    11111111111111111111111111111111 //-1

    //and

    ~100 //4
    =
    11111111111111111111111111111011 //-5

    //and

    ~1111111111111111111111111111111 //2147483647 (not to be confused with -1, which has 32 bits, not 31)
    =
    10000000000000000000000000000000 //-2147483648 (32nd bit turned on)

    If you dont understand why the negative values are sort of "backwards" please read the section about signed integers.
  • Bit Shifting

    Bit shifting does exactly what you would imagine it does; it shifts the bits in a number towards a certain direction. If you remember earlier in the article i mentioned that PAWN has a specific memory range (32 bits that can be used for storage). What happens when you shift a number past that range? The answer to this question lies in what shifting operator you are using, and what direction you are shifting in.


    NOTE: In the following examples, all binary numbers will be written out in full (all 32 bits) to avoid any confusions.

    • Arithmetic shifts

      • Right shift

        All bits in a number are shifted x amount of times to the right when using this operator. Lets takes a quick look at a simple example.

        pawn Code:
        00000000000000000000000000001000  //8
        >>
        2

        =

        00000000000000000000000000000010 //2

        You can see from the preceding example that every bit has moved to the right by two places, and two zeros were added on the left side as padding. These two zeros are actually the value of the MSB (Most significant bit) and are very important when it comes to signed integer shifting. The reason the MSB is used as padding is so we keep the sign of the number that is being shifted. Lets take a look at the same example, except lets make it negative.

        pawn Code:
        11111111111111111111111111111000 //-8
        >>
        2

        =

        11111111111111111111111111111110 //-2

        Clearly this behaves exactly the same as the previous example, except the left bits used for padding are ones; which proves that the padding of right arithmetic shift is the value of the MSB.

      • Left shift

        This is the exact opposite of the right arithmetic shifting operator. It shifts all the bits in a number to the left x amount of times. Lets look at an example.

        pawn Code:
        00000000000000000000000000001000  //8
        <<
        2

        =

        00000000000000000000000000100000 //32

        The only difference between the left and right arithmetic shift (besides the direction of the shift) would be the way it handles padding. With the right arithmetic shift, the padding is the value of the MSB (Most significant bit), but with the left arithmetic shift the value is just 0. This is because there is no relevant information like a number's sign to keep track of.

        pawn Code:
        11111111111111111111111111111000 //-8
        <<
        2

        =

        11111111111111111111111111100000 //-32

        See? Even though the padding is always 0, the sign of the number is still kept. The only thing you really have to worry about is shifting to far. If you shift a positive number past the highest possible number, it will become negative and vise versa with negative values (you'll eventually hit 0).

    • Logical Shifts

      • Right shift

        This is the converse to the arithmetic left shift. The best way to describe it would be a hybrid between the two arithmetic shifts. Lets take a look at it in action!


        pawn Code:
        00000000000000000000000000001000  //8
        >>>
        2

        =

        00000000000000000000000000000010 //2

        The bits in the number 8 where shifted 2 times to the right. So how is this any different from the arithmetic right shift? The answer is the padding. With the arithmetic right shift, the padding is the value of the MSB, but with the logical right shift the padding is just 0 (just as it is with the arithmetic left shift). This means that it will not keep the number of the sign, and our result will always be positive. To prove this, lets shift a negative number!


        pawn Code:
        11111111111111111111111111111000 //-8
        >>>
        2

        =

        00111111111111111111111111111110 //1073741822

        That proves that we wont get any negative values while using the logical right shift!

      • Left shift

        There is no logical left shift, as it would do exactly the same as the arithmetic left shift. I just added this to avoid confusion of any sort, and also to keep the section balanced.
Kyosaur is offline   Reply With Quote
Old 18/09/2010, 11:52 AM   #2
Kyosaur
Gangsta
 
Kyosaur's Avatar
 
Join Date: Mar 2008
Location: USA - California
Posts: 973
Reputation: 349
Default Re: An in-depth look at binary and binary operators.

Reserved.


EDIT: inb4 "0b" for binary numbers (i'll add it in, i just forgot it ).
Kyosaur is offline   Reply With Quote
Old 18/09/2010, 12:07 PM   #3
LarzI
High-roller
 
LarzI's Avatar
 
Join Date: Apr 2007
Location: Norway
Posts: 2,628
Reputation: 136
Default Re: An in-depth look at binary and binary operators.

Great tutorial!
Learned alot from it!

I still (as I'm only 16 years old) don't know in what situation I can take use of binary, but oh well.. I'll find out sooner or later.

Again, amazingly done!
__________________


NEW: [FS] Simple Cellphones

if( strfind( title, "REP", true ) != -1 )
{________________________________________
Sigh();__________________________
}________________________________________


LarzI is offline   Reply With Quote
Old 18/09/2010, 12:18 PM   #4
Hiddos
High-roller
 
Hiddos's Avatar
 
Join Date: Sep 2008
Posts: 3,304
Reputation: 2184
Default Re: An in-depth look at binary and binary operators.

The thing that's so fun about binary is that you can have any possible numbers, even when you think it seems impossible lmao.

Learned a lot from this, and I also mentioned that a specific bit equals all previous bits turned on minus one, for example:

pawn Code:
1000000 //64
 111111 //63

This is great for me, even though I don't quite exactly know when I could use it haha.

I'm also wondering on one thing: Is it possible to use this system (And it's operators) in PAWN?
__________________
Quote:
Originally Posted by DeWolf View Post
For fuck's sake people, this whole thread is fucked up now.
Hiddos is offline   Reply With Quote
Old 18/09/2010, 12:19 PM   #5
Leeroy.
Big Clucker
 
Leeroy.'s Avatar
 
Join Date: Sep 2010
Posts: 188
Reputation: 0
Default Re: An in-depth look at binary and binary operators.

you could have also showed Hexadecimal to binary which is commonly used in pawno.

Nice tut
Leeroy. is offline   Reply With Quote
Old 18/09/2010, 12:22 PM   #6
Kyosaur
Gangsta
 
Kyosaur's Avatar
 
Join Date: Mar 2008
Location: USA - California
Posts: 973
Reputation: 349
Default Re: An in-depth look at binary and binary operators.

Quote:
Originally Posted by LarzI View Post
Great tutorial!
Learned alot from it!

I still (as I'm only 16 years old) don't know in what situation I can take use of binary, but oh well.. I'll find out sooner or later.

Again, amazingly done!

Well, look at the key checking method everyone uses :P. That right there uses the bitwise AND operator.


You can use binary as a way to store multiple bool values (can stuff 31 bools in a single variable) as well. To do this you would use bitwise AND once again to check if the bit is set, and use the exclusive operator to toggle it on and off. ****** has a pre-written system in YSI which allows you to store more than 31 values (using arrays of course), i haven't personally checked it out yet though.


Off topic: First one to figure out what this macro does wins a high five!

Code:
#define FUNC_NAME(%0) ((%0) & 0x80000000)?(~(%0) + 0b1):(%0)
Its not efficient by any means (there is a WAY easier way to do it, and it also pwns this one in speed), but its a nice little "test" thing i guess.


Edit:

My grammar has gone to hell, i obviously need to get some sleep lol.


@Hiddos - yes, everything in here can be used in pawn. Also, when using the operators the numbers do not have to be a physical binary number (which in pawn is preceded by "0b" like hex is with "0x" :P) i would hope everyone would already understand after reading my post lol. Things like:

Code:
Tmp = Var << 3;
Tmp = Var & 4;
Tmp = Var ^ 5;

//and 

Var <<= 3;
Var &= 4;
Var ^= 5;

//etc
work perfectly fine.

Last edited by Kyosaur; 18/09/2010 at 12:43 PM.
Kyosaur is offline   Reply With Quote
Old 18/09/2010, 12:23 PM   #7
LarzI
High-roller
 
LarzI's Avatar
 
Join Date: Apr 2007
Location: Norway
Posts: 2,628
Reputation: 136
Default Re: An in-depth look at binary and binary operators.

Quote:
Originally Posted by Hiddos View Post
The thing that's so fun about binary is that you can have any possible numbers, even when you think it seems impossible lmao.

Learned a lot from this, and I also mentioned that a specific bit equals all previous bits turned on minus one, for example:

pawn Code:
1000000 //64
 111111 //63

This is great for me, even though I don't quite exactly know when I could use it haha.

I'm also wondering on one thing: Is it possible to use this system (And it's operators) in PAWN?
If it's possible to use binary in PAWN?
Well of course! That's why he made this tutorial.. x)

Look up the PAWN language guide! (Y)
__________________


NEW: [FS] Simple Cellphones

if( strfind( title, "REP", true ) != -1 )
{________________________________________
Sigh();__________________________
}________________________________________


LarzI is offline   Reply With Quote
Old 18/09/2010, 12:26 PM   #8
Mimic
Huge Clucker
 
Mimic's Avatar
 
Join Date: Jul 2010
Posts: 203
Reputation: 6
Default Re: An in-depth look at binary and binary operators.

Nicely done great tutorial
__________________
Coming soon
Mimic is offline   Reply With Quote
Old 18/09/2010, 12:27 PM   #9
Hiddos
High-roller
 
Hiddos's Avatar
 
Join Date: Sep 2008
Posts: 3,304
Reputation: 2184
Default Re: An in-depth look at binary and binary operators.

Quote:
Originally Posted by Kyosaur View Post
First one to figure out what this macro does wins a high five!

Code:
#define FUNC_NAME(%0) ((%0) & 0x80000000)?(~(%0) + 0b1):(%0)
Just an idea: It translates hexadecimal code to binary code D

And thanks LarzI, I'll try something out then hehe.
__________________
Quote:
Originally Posted by DeWolf View Post
For fuck's sake people, this whole thread is fucked up now.
Hiddos is offline   Reply With Quote
Old 18/09/2010, 12:34 PM   #10
Kyosaur
Gangsta
 
Kyosaur's Avatar
 
Join Date: Mar 2008
Location: USA - California
Posts: 973
Reputation: 349
Default Re: An in-depth look at binary and binary operators.

Quote:
Originally Posted by Hiddos View Post
Just an idea: It translates hexadecimal code to binary code D

And thanks LarzI, I'll try something out then hehe.
ok, if you say so:

Code:
0b10000000000000000000000000000000
Using a physical binary number is a pain, as they can get pretty long lol.


Edit:

Sorry i misread this, i thought you asked me to convert the hex to binary. No, it doesnt convert hex into binary. Hexadecimal and binary are just different numeral systems, there is nothing to convert if the values are the same. The only thing different between hex and binary is how they represent our value.

Code:
0b1011  //binary representation for 11
0xB      //Hex representation for 11
Both the above equal 11, its just they are represented differently, which is noted by the pawn constant "0b" for binary and pawn constant "0x" for hex.

Last edited by Kyosaur; 10/01/2011 at 11:22 PM.
Kyosaur is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Binary Tree insead of strcmp RSX Help Archive 2 06/09/2010 08:38 PM
Operators: <<= and >>= Vince Help Archive 1 16/06/2010 07:20 PM
[2 Random Questions] About zcmd/dcmd and some math operators [Marevin*] Help Archive 7 06/11/2009 03:00 PM
2 operators that i don't understand ғαιιοцт Help Archive 14 27/02/2009 04:50 PM


All times are GMT. The time now is 09:12 PM.


Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.