[Tutorial] An in-depth look at binary and binary operators.
#21

Quote:
Originally Posted by Hiddos
View Post
Took some time to make this awesome system save in my mind, I'm still wondering about this: What is the correct usage for binary in pawn, when working with variables? Does it work a bit like:

pawn Code:
new var = 68;
if(var & 32) print("Var has the 6th bit switched on!");
Or is it more like how it's exactly stated:

pawn Code:
new var = 68;
if(var & 100000) print("Var has the 6th bit switched on!");
Any advice would be great, it'd be fun to experiment to get a single variable into a bool of 31 arrays (Yes, I know somebody will be a jerk about that )
That piece of code there, I can't actually figure out how it works..
I mean, on the first page you explained that bitwise AND (&) will return as 0 if no bits are shared..
And after what I saw, 68 and 32 does not share any bits..

68 = 1000100
32 = 0100000

And if you then do
pawn Code:
if(68 & 32)
that would return false (or 0).. Wouldn't it?
Reply
#22

Quote:
Originally Posted by Chaprnks
View Post
Very useful tutorial. I never knew what most of those operators actually did until now.
Thanks, glad it helped you .

Quote:
Originally Posted by MrDeath
View Post
Very very nice tutorial, so, when should I use binary?

Thanks you.
If you have to ask that, you probably should reread the article. Also some previous posts have examples in them, you should check them out if you havent.

Quote:
Originally Posted by LarzI
View Post
That piece of code there, I can't actually figure out how it works..
I mean, on the first page you explained that bitwise AND (&) will return as 0 if no bits are shared..
And after what I saw, 68 and 32 does not share any bits..

68 = 1000100
32 = 0100000

And if you then do
pawn Code:
if(68 & 32)
that would return false (or 0).. Wouldn't it?
I dont see how you do not understand his code, as you just explained it. It seems to me like you DO get it :P.

Since the check came out to be false, the print wont be called. Is this what you're getting stuck on?
Reply
#23

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!
Check this out: http://www.cplusplus.com/forum/general/1590/

Flags. Study and give the code below a try:
*Note: GetBit is only there for ease of understanding, it'd be simpler just to use the comments in the functions rather than what is currently in use.
Code:
#include <a_samp>

#define FILTERSCRIPT

GetBit(flag)
{
	return (1 << flag);
}

FlagOn(&mask, flag)
{
	mask |= flag;
	// mask |= (1 << flag);
}

FlagOff(&mask, flag)
{
	mask &= (~flag);
	// mask &= ~(1 << flag);
}

HasFlag(mask, flag)
{
	return (mask & flag);
	// return (mask & (1 << flag));
}

public OnFilterScriptInit()
{
	new
	    flags = 0x0,
		i;
	    
	for(i = 0; i < 31; ++i)
	{
	    FlagOn(flags, GetBit(i));
	    printf("Bit: %b, Flag Active: %i", GetBit(i), HasFlag(flags, GetBit(i)));
	}

	for(i = 0; i < 31; ++i)
	{
	    FlagOff(flags, GetBit(i));
	    printf("Bit: %b, Flag Active: %i", GetBit(i), HasFlag(flags, GetBit(i)));
	}

	return 0;
}
And if you're further interested, study this:
Code:
#include <a_samp>

#define FILTERSCRIPT

Pack(&mask, byte, value)
{
	mask |= ((value & 0xff) << (byte * 8));
}

UnPack(&mask, byte)
{
    mask &= ~(PackGet(mask, byte) << (byte * 8));
}

PackGet(mask, byte)
{
	return ((mask >> (byte * 8)) & 0xff);
}

public OnFilterScriptInit()
{
	new
	    mask = 0x0,
	    i;

	for(i = 0; i < 4; ++i)
	{
	    Pack(mask, i, random(255));
	    printf("Byte: %i, Value: %i", i, PackGet(mask, i));
 	}
	    
	for(i = 0; i < 4; ++i)
	{
	    UnPack(mask, i);
	    printf("Byte: %i, Value: %i", i, PackGet(mask, i));
 	}

	return 0;
}
Since Pawn's cell data type is 32-bits wide, you're able to store 4 "unsigned" 8-bit integers in your mask.



Enjoy!
Reply
#24

Quote:
Originally Posted by Kyosaur
View Post
I dont see how you do not understand his code, as you just explained it. It seems to me like you DO get it :P.

Since the check came out to be false, the print wont be called. Is this what you're getting stuck on?
Presicely... :P
Reply
#25

Quote:
Originally Posted by Tannz0rz
View Post
Check this out: http://www.cplusplus.com/forum/general/1590/

Flags. Study and give the code below a try:
*Note: GetBit is only there for ease of understanding, it'd be simpler just to use the comments in the functions rather than what is currently in use.
Code:
#include <a_samp>

#define FILTERSCRIPT

GetBit(flag)
{
	return (1 << flag);
}

FlagOn(&mask, flag)
{
	mask |= flag;
	// mask |= (1 << flag);
}

FlagOff(&mask, flag)
{
	mask &= (~flag);
	// mask &= ~(1 << flag);
}

HasFlag(mask, flag)
{
	return (mask & flag);
	// return (mask & (1 << flag));
}

public OnFilterScriptInit()
{
	new
	    flags = 0x0,
		i;
	    
	for(i = 0; i < 31; ++i)
	{
	    FlagOn(flags, GetBit(i));
	    printf("Bit: %b, Flag Active: %i", GetBit(i), HasFlag(flags, GetBit(i)));
	}

	for(i = 0; i < 31; ++i)
	{
	    FlagOff(flags, GetBit(i));
	    printf("Bit: %b, Flag Active: %i", GetBit(i), HasFlag(flags, GetBit(i)));
	}

	return 0;
}
And if you're further interested, study this:
Code:
#include <a_samp>

#define FILTERSCRIPT

Pack(&mask, byte, value)
{
	mask |= ((value & 0xff) << (byte * 8));
}

UnPack(&mask, byte)
{
    mask &= ~(PackGet(mask, byte) << (byte * 8));
}

PackGet(mask, byte)
{
	return ((mask >> (byte * 8)) & 0xff);
}

public OnFilterScriptInit()
{
	new
	    mask = 0x0,
	    i;

	for(i = 0; i < 4; ++i)
	{
	    Pack(mask, i, random(255));
	    printf("Byte: %i, Value: %i", i, PackGet(mask, i));
 	}
	    
	for(i = 0; i < 4; ++i)
	{
	    UnPack(mask, i);
	    printf("Byte: %i, Value: %i", i, PackGet(mask, i));
 	}

	return 0;
}
Since Pawn's cell data type is 32-bits wide, you're able to store 4 "unsigned" 8-bit integers in your mask.



Enjoy!
Nice post, thanks for contributing .

I mentioned the first method in previous posts, i just never gave physical code (thank you for providing it heh). You could take it a step further and convert your functions into defines, would be faster that way.

I'm not so sure about the second method though. Im all for saving memory, but i dont think the speed difference would be worth it for 4 unsigned 8 bit integers. That's just my view though, there's nothing wrong with it at all. To be honest, i never even thought about this once. Its pretty neat at the very least.
Reply
#26

hey.. I put code too! : (
http://forum.sa-mp.com/showpost.php?...3&postcount=19

btw, to create arrays with unsigned 8bit integers, simply use the "char" keyword.


pawn Code:
new array[ 4 char ];

array{ 0 } = 10;
array{ 1 } = 20;
array{ 2 } = 30;
array{ 3 } = 40;

printf( "%d %d %d %d", array{ 0 }, array{ 1 }, array{ 2 }, array{ 3 } );
thanks Y_Less for reminding me about the curly brackets


Quote:
Originally Posted by Kyosaur
View Post
I'm not so sure about the second method though. Im all for saving memory, but i dont think the speed difference would be worth it for 4 unsigned 8 bit integers. That's just my view though, there's nothing wrong with it at all. To be honest, i never even thought about this once. Its pretty neat at the very least.
Say you have around 10 arrays size 500 that don't have values higher than 255 or lower than 0. Storing those in 4-byte cells would use a total of 20000 bytes, roughly 20kb. If you were using the arrays for packed strings, you would use only 5000 bytes (5 kb).

Also,
For arrays containing onle true/false, you could store those in each bit; resulting in 32 true/false values per cell. For a bit array size 500, would need only 16 cells! Comparing that to a normal array, you would save roughly 2kb for just one array!
Reply
#27

Quote:
Originally Posted by g_aSlice
View Post
hey.. I put code too! : (
http://forum.sa-mp.com/showpost.php?...3&postcount=19

btw, to create arrays with unsigned 8bit integers, simply use the "char" keyword.


pawn Code:
new array[ 4 char ];

array{ 0 } = 10;
array{ 1 } = 20;
array{ 2 } = 30;
array{ 3 } = 40;

printf( "%d %d %d %d", array{ 0 }, array{ 1 }, array{ 2 }, array{ 3 } );
thanks Y_Less for reminding me about the curly brackets
Oh forgive me, i forgot to reply to you, sorry .

You previous post looks ok, i assume you chose the OnPlayerUpdate method only as an example to display a use for the XOR operator. If thats what you were doing, good job. You should probably note that ideally you would use the OnPlayerKeyStateChange callback though, and that it was just an example.

I've never really played with packed strings before, so i know very little when it comes to the char operator. So cant really comment on this subject. Im not sure if i'll even mess with it (the operator in general) to be honest, it seems like a ton of work for saving a bit of ram (also i imagine unpacking/checking for it would just be slow, so not sure if its worth it to me).


EDIT

Quote:
Originally Posted by g_aSlice
View Post
Say you have around 10 arrays size 500 that don't have values higher than 255 or lower than 0. Storing those in 4-byte cells would use a total of 20000 bytes, roughly 20kb. If you were using the arrays for packed strings, you would use only 5000 bytes (5 kb).
Im well aware of the benefits, im just not willing to sacrifice speed for 15k of ram lol. Im fine with using the first method though (i've actually been using it for a while) as its not as slow as the packing alternative, and i can stuff more into a single variable.

In order for me to sacrifice speed for memory (which i have a lot of) it has to be pretty well worth it to me lol.
Reply
#28

Oh no it wouldn't slow down at all. I actually benchmarked it and the access time to char arrays was slightly quicker.
Basically the only thing char does it declare it as a 1-byte array as opposed to a 4-byte.

Also, yeah, I used OnPlayerUpdate only for the example.
Reply
#29

Quote:
Originally Posted by g_aSlice
View Post
Oh no it wouldn't slow down at all. I actually benchmarked it and the access time to char arrays was slightly quicker.
Basically the only thing char does it declare it as a 1-byte array as opposed to a 4-byte.
Erm by packing in my last quote (after the edit), i meant the method of shoving 4 unsigned 8bit integers into a single variable (via the pack functions posted by Tannz0rz). Sorry about the confusion lol, I'm a litte out of it from staying up all night.

I'll take a look into the char operator (in general, not just for binary related storage), my only complaint is the additional checking and unpacking i'd have to do (which would affect speed).


Either way, thanks again for sharing your method .

EDIT:

Quote:
Originally Posted by g_aSlice
View Post
There is no unpacking to do with the char keyword! That's only if you're using strings.
Quote:

I'll take a look into the char operator (in general, not just for binary related storage), my only complaint is the additional checking and unpacking i'd have to do (which would affect speed).

hehe
Reply
#30

There is no unpacking to do with the char keyword! That's only if you're using strings.
Reply
#31

I think I'm starting to understand now..

For an example, in key checks..

This
pawn Код:
if( newkeys & KEY_JUMP )
Will that be
pawn Код:
//if( newkeys & 32 )
if( newkeys & 100000 )
which will return true if newkeys is using the 6th bit? (32)
Reply
#32

Quote:
Originally Posted by LarzI
Посмотреть сообщение
I think I'm starting to understand now..

For an example, in key checks..

This
pawn Код:
if( newkeys & KEY_JUMP )
Will that be
pawn Код:
//if( newkeys & 32 )
if( newkeys & 100000 )
which will return true if newkeys is using the 6th bit? (32)
Well, technically speaking it'd be:
pawn Код:
if(newkeys & 0b100000)
But yes, that is correct.
Reply
#33

Quote:
Originally Posted by Tannz0rz
Посмотреть сообщение
Well, technically speaking it'd be:
pawn Код:
if(newkeys & 0b100000)
But yes, that is correct.
Thank you for clearing that up. Appreciate it
Reply
#34

Question about the bit operators in if-statements:

Ok, I'm using the "32 bools in one variable" method now, and I got it all working except one thing.

I can check if a value is set like this:

pawn Код:
if(bSettings & setting1)
but how do I check if the bit isn't set?

pawn Код:
if(bSettings (?) setting1)
I got confused with the bit operators
Reply
#35

Quote:
Originally Posted by [HLF]Southclaw
Посмотреть сообщение
Question about the bit operators in if-statements:

Ok, I'm using the "32 bools in one variable" method now, and I got it all working except one thing.

I can check if a value is set like this:

pawn Код:
if(bSettings & setting1)
but how do I check if the bit isn't set?

pawn Код:
if(bSettings (?) setting1)
I got confused with the bit operators
Exactly the same way! If you can check if something is true (ie the bit is on), you can also check if it is false. You can use the logical NOT operator (!), or even an else statement.

Код:
if(!(bSettings & FLAG))
{
    //not set
}
or

Код:
if(bSettings & FLAG)
{
    //Set
}
else
{
    //Not set
}
Pretty simple :P. By the way, check out the functions that Tannz0rz posted. You can convert them into macros and have a nice little system .
Reply
#36

What is this?
Maths tutorial? xD
Reply
#37

If you read the title you know what it is...
Reply
#38

Quote:
Originally Posted by alpha500delta
Посмотреть сообщение
If you read the title you know what it is...
Exactly lol.



Edit: Since this topic has been bumped a few times, im gonna do a nice edit to it. Im gonna try to make the article more clear, include the constant "0b" for binary numbers, and add a section for usage of binary.


I should be done in a couple days ... its all depending on how much down time i have (I could have it done tonight if im lucky :P).
Reply
#39

Ah, thanks Kyosaur I tried using the logical-not but didn't add the brackets so it failed:

pawn Код:
if(!bSet & setting)
Forgot about how brackets can fix things like that thanks and can't wait til the update
Reply
#40

I actually learned from it, thank you for this great tutorial.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)