rBits [supports 16, 8, 4, 2 and 1-bit arrays] -
RyDeR` - 08.08.2011
Introduction
Last days I did some research regarding bit manipulation and extractions and ended up with this small, very useful include. This include will save you lots of memory if you use it efficient.
Integer Limits
| 1-Bit | 2-Bit | 4-Bit | 8-Bit | 16-Bit |
Limit | 1 ─ 0x1 | 3 ─ 0x3 | 15 ─ 0xF | 255 ─ 0xFF | 65535 ─ 0xFFFF |
A higher/lower value will just repeat until the limit and start over again till done.
Usage
Declaration
The syntax is quite simple. You just use
BitX and replace
X with the prefered bit type as tag, followed by the name and then the size between
< and
>.
So for example let's declare a 4-bit array
b4_Nibble with a size of
32:
pawn Код:
new
Bit4: b4_Nibble <32>
;
Set and get a bit
You can use the
BitX_Set/Get function for this. For example:
pawn Код:
Bit4_Set(b4_Nibble, 0, 4);
This will set
b4_Nibble at index
0 to a value of
4.
Retrieving the value is as simple as:
This will return the value in
b4_Nibble at index
0 which will be
4 in this case.
Examples
Here are some simple examples of what I mean by "saving lots of memory". I often see people doing things like this:
pawn Код:
#include <a_samp>
new
bool: g_PlayerSpawned[MAX_PLAYERS]
;
public OnPlayerSpawn(playerid) {
g_PlayerSpawned[playerid] = true;
}
public OnPlayerDeath(playerid) {
g_PlayerSpawned[playerid] = false;
}
public OnPlayerDisconnect(playerid, reason) {
g_PlayerSpawned[playerid] = false;
}
stock IsPlayerSpawned(playerid) {
return g_PlayerSpawned[playerid];
}
The .amx size after compile is
726 bytes. Nothing much, but as you can see we're using 32-bit variables for only 0 and 1, so that's a waste of a lot memory. The most relevant bit type in this case would be 1-bit:
pawn Код:
#include <a_samp>
#include <rBits>
new
Bit1: g_PlayerSpawned <MAX_PLAYERS>
;
public OnPlayerSpawn(playerid) {
Bit1_Set(g_PlayerSpawned, playerid, true);
}
public OnPlayerDeath(playerid) {
Bit1_Set(g_PlayerSpawned, playerid, false);
}
public OnPlayerDisconnect(playerid, reason) {
Bit1_Set(g_PlayerSpawned, playerid, false);
}
stock IsPlayerSpawned(playerid) {
return Bit1_Get(g_PlayerSpawned, playerid);
}
The .amx size of this after compile is only
473 bytes. Probably not a big deal right now, but imagine with larger arrays or just a couple of more arrays like this.
This is just analog all the rest of the bit-types, just make sure you pick the right bit-type for your value.
Download
rBits.inc
FAQ
- How can I use this with enum?
- You can just sort per bit type. For example for 1-bit arrays:
pawn Код:
enum e_Bit1_Data {
e_bSpawned,
e_bIsDeath,
e_bInDM,
// ...
};
new
g_Bit1_Data[e_Bit1_Data] <MAX_PLAYERS>
;
Bit1_Set(g_Bit1_Data[e_bSpawned], playerid, true);
Bit1_Get(g_Bit1_Data[e_bSpawned], playerid);
- How to increase/decrease the value?
- Since x++ is equal to x = x + 1 we can simply use that technique:
pawn Код:
Bit4_Set(b4_Nibble, 0, Bit4_Get(b4_Nibble, 0) + 1);
- Other questions?
Re: rBits [supports 16, 8, 4, 2 and 1-bit arrays] -
Ash. - 08.08.2011
Nice Ryder! I'd thought about this in the past, but aren't you leaving yourself open to possible overflows? (I haven't looked at the source code yet, so I'm probably wrong)
Re: rBits [supports 16, 8, 4, 2 and 1-bit arrays] -
VivianKris - 08.08.2011
Nice I will try it!
Re: rBits [supports 16, 8, 4, 2 and 1-bit arrays] -
Zh3r0 - 08.08.2011
Now I understand what bits are, thanks a lot for this.
So normal variables are 32bits? Which means they can store a high amount of data but we only need 0 and 1.
Whenever we use a variable to just check something if it's true or false we simply use the 1bit array right?
And when we count a variable we just use the 16bit?
Re: rBits [supports 16, 8, 4, 2 and 1-bit arrays] -
RyDeR` - 08.08.2011
Quote:
Originally Posted by funky1234
Nice Ryder! I'd thought about this in the past, but aren't you leaving yourself open to possible overflows? (I haven't looked at the source code yet, so I'm probably wrong)
|
There's a small piece of code involved which checks if you exceed the array bounds so I guess this is quite safe.
Quote:
Originally Posted by Zh3r0
So normal variables are 32bits?
|
Yes.
Quote:
Originally Posted by Zh3r0
Which means they can store a high amount of data but we only need 0 and 1. Whenever we use a variable to just check something if it's true or false we simply use the 1bit array right?
|
Yes.
Quote:
Originally Posted by Zh3r0
And when we count a variable we just use the 16bit?
|
No, you just use the value you need and nothing more. If you use 16-bit arrays, you can save a maximum amount of 65535 like I said in the topic (see limits).
Re: rBits [supports 16, 8, 4, 2 and 1-bit arrays] -
Zh3r0 - 08.08.2011
Quote:
Originally Posted by RyDeR`
There's a small piece of code involved which checks if you exceed the array bounds so I guess this is quite safe.
No, you just use the value you need and nothing more. If you use 16-bit arrays, you can save a maximum amount of 65535 like I said in the topic (see limits).
|
Ah yes, true, I meant 4-bit array, then the 4bit array will do it right, and it also doesn't exceed alpha opacity xD
(Which is the right thing I need)
I'm switching right NOW!, Thanks again. Good job.
Re: rBits [supports 16, 8, 4, 2 and 1-bit arrays] -
Kaperstone - 08.08.2011
nice
Re: rBits [supports 16, 8, 4, 2 and 1-bit arrays] -
OUL - 08.08.2011
This is awesome i'm gonna use this
Re: rBits [supports 16, 8, 4, 2 and 1-bit arrays] -
RyDeR` - 08.08.2011
Quote:
Originally Posted by xkirill
nice 
can u make Minimum random number to?
|
What do you exactly mean by that? The examples are just examples on how to use it, don't get confused by that please.
Re: rBits [supports 16, 8, 4, 2 and 1-bit arrays] -
OUL - 08.08.2011
I mean he think on something like this
RandomEx(min, max)
but that's posible and easy to make use 'Min, Max' fnc
OFF TOPIC
Re: rBits [supports 16, 8, 4, 2 and 1-bit arrays] -
Zh3r0 - 08.08.2011
Does this work with enums? Forgot to question this.
Re: rBits [supports 16, 8, 4, 2 and 1-bit arrays] - Double-O-Seven - 08.08.2011
How about this:
pawn Код:
bitLim = ((1 << (1 << _: bitShift)) - 1)
//Case Bit1: (1 << (1 << 0) - 1 = (1 << 1) - 1 = 2 - 1 = 1 is correct!
//Case Bit2: (1 << (1 << 1) - 1 = (1 << 2) - 1 = 4 - 1 = 3 is correct!
//Case Bit4: (1 << (1 << 2) - 1 = (1 << 4) - 1 = 16 - 1 = 15 is correct!
//Case Bit8: (1 << (1 << 3) - 1 = (1 << 8) - 1 = 256 - 1 = 255 is correct!
//Case Bit16: (1 << (1 << 4) - 1 = (1 << 16) - 1 = 65536 - 1 = 65535 is correct!
//I had to test it because I wasn't sure 100% test.
//OK; Now I'm sure because a shift is a multiplication by 2. And 1 << x == 2 ^ x where ^ denotes power.
Instead of this:
pawn Код:
bitLim = ((1 << floatround(floatpower(2.0, _: bitShift))) - 1)
Re: rBits [supports 16, 8, 4, 2 and 1-bit arrays] -
Zh3r0 - 08.08.2011
Can anyone answer my question? I'm kinda in a hurry, thanks.
Re: rBits [supports 16, 8, 4, 2 and 1-bit arrays] -
vyper - 08.08.2011
Great include

I gonna use it thanks
Re: rBits [supports 16, 8, 4, 2 and 1-bit arrays] -
OUL - 08.08.2011
One more question, what about YSI - ybit's are that work on this way too?
And how to use 'if' statement with this rBits (if i can use) or i need to make something like this evry time?
pawn Код:
IsAVariable ( playerid ) return Bit1_Get ( iVariable, playerid );
Re: rBits [supports 16, 8, 4, 2 and 1-bit arrays] - Double-O-Seven - 08.08.2011
Quote:
Originally Posted by OUL
One more question, what about YSI - ybit's are that work on this way too?
And how to use 'if' statement with this rBits (if i can use) or i need to make something like this evry time?
pawn Код:
IsAVariable ( playerid ) return Bit1_Get ( iVariable, playerid );
|
y_bit only supports BitArrays (1bit-arrays, Bit1 in this include).
For if-statements: if (BitX_Get (...)) { /*do something*/ }...
Re: rBits [supports 16, 8, 4, 2 and 1-bit arrays] -
OUL - 08.08.2011
Thanks, then very good work Ryder
Is BitGet in boolean type?
so i can use:
pawn Код:
if( BitN_Get ( iVariable, playerid ) == false/true)
Re: rBits [supports 16, 8, 4, 2 and 1-bit arrays] -
RyDeR` - 08.08.2011
Quote:
Originally Posted by Zh3r0
Does this work with enums? Forgot to question this.
|
What do you exactly mean. Give me an example with normal arrays.
Quote:
Originally Posted by Double-O-Seven
How about this:
pawn Код:
bitLim = ((1 << (1 << _: bitShift)) - 1) //Case Bit1: (1 << (1 << 0) - 1 = (1 << 1) - 1 = 2 - 1 = 1 is correct! //Case Bit2: (1 << (1 << 1) - 1 = (1 << 2) - 1 = 4 - 1 = 3 is correct! //Case Bit4: (1 << (1 << 2) - 1 = (1 << 4) - 1 = 16 - 1 = 15 is correct! //Case Bit8: (1 << (1 << 3) - 1 = (1 << 8) - 1 = 256 - 1 = 255 is correct! //Case Bit16: (1 << (1 << 4) - 1 = (1 << 16) - 1 = 65536 - 1 = 65535 is correct! //I had to test it because I wasn't sure 100% test. //OK; Now I'm sure because a shift is a multiplication by 2. And 1 << x == 2 ^ x where ^ denotes power.
Instead of this:
pawn Код:
bitLim = ((1 << floatround(floatpower(2.0, _: bitShift))) - 1)
|
That's even better! Changing right now, thanks.
Re: rBits [supports 16, 8, 4, 2 and 1-bit arrays] -
OUL - 08.08.2011
Ryder @enums
pawn Код:
enum iData { SomeVar };
new
PlayerInfo[MAX_PLAYERS][iData];
How to use in that case rBit?
Re: rBits [supports 16, 8, 4, 2 and 1-bit arrays] -
Zh3r0 - 08.08.2011
Quote:
Originally Posted by RyDeR`
What do you exactly mean. Give me an example with normal arrays.
That's even better! Changing right now, thanks.
|
I mean, I have an enum, and want to use the enum.
pawn Код:
enum pData { level, etc, etc2 };
new Pi[MAX_PLAYERS][pData];
That's an example, how do I do it with enums?
@OUL Same time, sorry
@Edit, How do I increment or decrease a value?
Ah, nevermind, I use bitx_get() + 1. Right?