Rules FAQ Members List Search Register Login

 Raised This Month: \$ Target: \$400 0%

Author Message
ot_207
Veteran Member
Join Date: Jan 2008
Location: Romania The Love Country
 04-19-2009 , 05:20   [INFO] Bitsums and Operators #1 About: This tutorial is meant for beginner scripters from amxx. This will teach you on how to use bitsum operators and show some advantages over boolean storage arrays! What is a bitsum? A bitsum is based on the way memory works. If we think, the memory chip containes cells (bits) that can hold 2 infos: 1 and 0. To store a number in one byte (byte = 8 bits) here is how to do it: "8" (normal number) = "00001000" (memory number [1 byte]) How does a bitsum work? Well the idea is that bitsums allow to control the position that we want to set it to 1. And we can check wether that position has 1 or 0. What operators do I have, and what do they mean? I will give an example for each operator: PHP Code: ``` Operator: | first_byte = "10010001" second_byte = "01010001" first_byte | second_byte = "11010001"  ``` So basically this operator works like the logical one || but it does the operation on each bit! Code: ```| 1 0 1 1 1 0 1 0``` PHP Code: ``` Operator: & first_byte = "10010001" second_byte = "01010001" first_byte & second_byte = "0001001"  ``` So basically this operator works like the logical one && but it does the operation on each bit! Code: ```& 1 0 1 1 0 0 0 0``` PHP Code: ``` Operator: ^ (Exclusive OR) first_byte = "10010001" second_byte = "01010001" first_byte ^ second_byte = "1100000"  ``` So basically this operator works like the logical one ^^ but it does the operation on each bit! Code: ```^ 1 0 1 0 1 0 1 0``` PHP Code: ``` Operator: ~ (Complement applies on only one number!) first_byte = "10010001" ~first_byte = "01101110"  ``` So basically this operator negates every bit! So 0 becomes 1 and 1 becomes 0. Code: ```~1 = 0 ~0 = 1``` How do normal numbers work? They are stored in the normal cells by base. So they are converted from base 10 from base 2. In this case number 9 for example becomse: "00001001". To comvert that number from the cells back to 9 we need to multiply each position with 2 and a power of it! 2^2 = power(2,2) = 4 00001001: 1*(2^0) + 0*(2^1) + 0*(2^2) + 1*(2^3) + 0*(2^4) + 0*(2^5) + 0*(2^6) + 0*(2^7) = 1 + 8 = 9 How can I easily create a bitsum? Well you need 2 operators: << and >>, or if you don't want to use those operators you can easily create one by using elements that represent powers of 2. Example: PHP Code: ``` Bitsum "00001111" = 8 | 4 | 2 | 1  ``` The 2 operators have a special meaning! "<< x" means that a position of a number is moved by x points to left! Example: PHP Code: ``` "00001100" << 1 = "00011000"  ``` When we convert this to normal number we can see that the normal number was multiplied by 2. So if we have (1<<3) it would be like 2^3 * 1 The >> operator does the same thing like << but moves x points to right! When using integer variables the numbers disappear. PHP Code: ``` "00000111" >> 3 = "00000000"  ``` So using those 2 operators to create a bitsum we have this: PHP Code: ``` Bitsum "00001111" = (1<<3 | 1<<2 | 1<<1 | 1<<0)  ``` How can I use this in my scripts? Well it can be used for insance instead of boolean arrays. So instead of having this: PHP Code: ``` new bool:is_alive[33]  ``` We have: PHP Code: ``` new bitsum_is_alive  ``` So less memory usage! Instead of PHP Code: ``` if (is_alive[id]) { }  ``` We have: PHP Code: ``` if (bistum_is_alive & (1<
Empowers
BANNED
Join Date: Feb 2009
Location: Ukraine
04-19-2009 , 09:04   Re: [INFO] Bitsums and Operators
#2

Wow thx for Great TUT!
Quote:
 Originally Posted by ot_207 So less memory usage!
Profiled:

Code:
```date: Sun Apr 19 15:20:28 2009 map: de_dust
type |                             name |      calls | time / min / max
-------------------------------------------------------------------
n |                   register_clcmd |          2 | 0.000019 / 0.000004 / 0.000015
p |                       array_test |         10 | 0.064196 / 0.006202 / 0.006642
p |                      bitsum_test |         10 | 0.029594 / 0.002811 / 0.003570
p |                      plugin_init |          1 | 0.000002 / 0.000002 / 0.000002
0 natives, 0 public callbacks, 3 function calls were not executed.```

Tested on this code:
PHP Code:
``` #include <amxmodx> new array[33] new bitsum public plugin_init()  {     array[32] = false              bitsum &=  ~(1<<32)           register_clcmd("array","array_test")     register_clcmd("bitsum","bitsum_test") } public bitsum_test() {     for(new i;i<=1_000_000;i++)         if(bitsum & (1<<32))             continue; } public array_test() {     for(new i;i<=1_000_000;i++)         if(array[32])             continue; }  ```

Now I'm thinking should I swap arrays with bitsums in my plugins code. It would use less memory, but it will be harder to understand the code.

Last edited by Empowers; 04-19-2009 at 12:00.
Veteran Member
Join Date: Dec 2008
Location: Portugal
04-19-2009 , 13:10   Re: [INFO] Bitsums and Operators
#3

Quote:
 Originally Posted by Empowers Wow thx for Great TUT! Profiled: Code: ``` Code: date: Sun Apr 19 15:20:28 2009 map: de_dust type | name | calls | time / min / max ------------------------------------------------------------------- n | register_clcmd | 2 | 0.000019 / 0.000004 / 0.000015 p | array_test | 10 | 0.064196 / 0.006202 / 0.006642 p | bitsum_test | 10 | 0.029594 / 0.002811 / 0.003570 p | plugin_init | 1 | 0.000002 / 0.000002 / 0.000002 0 natives, 0 public callbacks, 3 function calls were not executed. Tested on this code: PHP Code: ``` #include new array[33]new bitsumpublic plugin_init() {    array[32] = false            bitsum &=  ~(1<<32)         register_clcmd("array","array_test")    register_clcmd("bitsum","bitsum_test")}public bitsum_test(){    for(new i;i<=1_000_000;i++)        if(bitsum & (1<<32))            continue;}public array_test(){    for(new i;i<=1_000_000;i++)        if(array[32])            continue;}  ``` Now I'm thinking should I swap arrays with bitsums in my plugins code. It would use less memory, but it will be harder to understand the code.```
That profile is wrong.
PHP Code:
``` #include <amxmodx>new array[3]new bitsumpublic Index(n){    return array[n]}public Bit(n){    return (bitsum & (1<<n))}public plugin_cfg(){    array[1] = true    bitsum   = (1 << 1)         for(new i;i<10000;i++)    {        Bit(1)        Index(1);        Bit(2);        Index(2);    }        server_cmd("quit");}  ```
HTML Code:
```date: Sun Apr 19 08:56:46 2009 map: de_dust2
type |                             name |      calls | time / min / max
-------------------------------------------------------------------
n |                       server_cmd |          1 | 0.000013 / 0.000013 / 0.000013
p |                       plugin_cfg |          1 | 0.088612 / 0.088612 / 0.088612
f |                              Bit |      20000 | 0.043302 / 0.000001 / 0.000040
f |                            Index |      20000 | 0.043490 / 0.000001 / 0.000104
0 natives, 2 public callbacks, 1 function calls were not executed.

date: Sun Apr 19 08:57:13 2009 map: de_dust2
type |                             name |      calls | time / min / max
-------------------------------------------------------------------
n |                       server_cmd |          1 | 0.000012 / 0.000012 / 0.000012
p |                       plugin_cfg |          1 | 0.094011 / 0.094011 / 0.094011
f |                              Bit |      20000 | 0.045281 / 0.000001 / 0.000012
f |                            Index |      20000 | 0.046318 / 0.000001 / 0.000488
0 natives, 2 public callbacks, 1 function calls were not executed.

date: Sun Apr 19 08:57:20 2009 map: de_dust2
type |                             name |      calls | time / min / max
-------------------------------------------------------------------
n |                       server_cmd |          1 | 0.000016 / 0.000016 / 0.000016
p |                       plugin_cfg |          1 | 0.092532 / 0.092532 / 0.092532
f |                              Bit |      20000 | 0.044500 / 0.000001 / 0.000023
f |                            Index |      20000 | 0.044818 / 0.000001 / 0.000137
0 natives, 2 public callbacks, 1 function calls were not executed.

date: Sun Apr 19 08:57:28 2009 map: de_dust2
type |                             name |      calls | time / min / max
-------------------------------------------------------------------
n |                       server_cmd |          1 | 0.000014 / 0.000014 / 0.000014
p |                       plugin_cfg |          1 | 0.095900 / 0.095900 / 0.095900
f |                              Bit |      20000 | 0.045795 / 0.000001 / 0.000194
f |                            Index |      20000 | 0.045659 / 0.000001 / 0.000117
0 natives, 2 public callbacks, 1 function calls were not executed.```
Bitsums can't be used to replace is_user_alive like you have it, because 1<<32 is out of the bits that a cell can hold.
__________________
Bugsy
AMX Mod X Moderator
Join Date: Feb 2005
Location: NJ, USA
04-19-2009 , 16:07   Re: [INFO] Bitsums and Operators
#4

Quote:
 Originally Posted by joaquimandrade Bitsums can't be used to replace is_user_alive like you have it, because 1<<32 is out of the bits that a cell can hold.
This is correct, since a 4 byte cell has 32 bits:
1 = 0000 0000 0000 0000 0000 0000 0000 0001

Doing a left shift of 32 will push the bit out of the bitfield:
1 << 32 = 1 0000 0000 0000 0000 0000 0000 0000 0000

You can make it work to hold player indexes (1-32) by subtracting 1 from the left-shift value so you will always shift 1 less (0-31 instead of 1-32). I used bit-fields in my Admin Hierarchy plugin instead of using arrays of 33 cells. The bit-field method is also nice because you can quickly check if any admins or bots are on the server with a simple !g_Bot or !g_Admin.

I cannot get the profiler to work so I'm not sure which way is ultimately better. The bit-field is better to conserve memory as you are using 1 cell (4 bytes) vs. a 33 cell array (132 bytes) as a storage mechanism for player indexes. On the other hand, the array method may be less CPU expensive but it will obviously utilize more memory.

PHP Code:
``` #define AddFlag(%1,%2)       ( %1 |= ( 1 << (%2-1) ) )#define RemoveFlag(%1,%2)    ( %1 &= ~( 1 << (%2-1) ) )#define CheckFlag(%1,%2)     ( %1 & ( 1 << (%2-1) ) )new g_Admin;new g_Bot;public client_putinserver(id){    if ( is_user_admin( id ) )    {        //An admin connected, add a bit to the g_Admin bitfield for this players id        AddFlag( g_Admin , id );    }    if ( is_user_bot( id ) )        AddFlag( g_Bot , id );}public client_disconnect(id){    if ( CheckFlag( g_Bot , id ) )    {        //bot disconnected        RemoveFlag( g_Bot , id );    }}public YourFunction(id){    if ( !CheckFlag( g_Admin , id ) )    {        //You are not an admin    }    if ( !g_Admin )         //There are no admins online!}  ```
__________________

Last edited by Bugsy; 04-19-2009 at 16:23.
Veteran Member
Join Date: Dec 2008
Location: Portugal
04-19-2009 , 16:33   Re: [INFO] Bitsums and Operators
#5

Quote:
 Originally Posted by Bugsy This is correct, since a 4 byte cell has 32 bits: 1 = 0000 0000 0000 0000 0000 0000 0000 0001 Doing a left shift of 32 will push the bit out of the bitfield: 1 << 32 = 1 0000 0000 0000 0000 0000 0000 0000 0000 You can make it work to hold player indexes (1-32) by subtracting 1 from the left-shift value so you will always shift 1 less (0-31 instead of 1-32). I used bit-fields in my Admin Hierarchy plugin instead of using arrays of 33 cells. The bit-field method is also nice because you can quickly check if any admins or bots are on the server with a simple !g_Bot or !g_Admin. I cannot get the profiler to work so I'm not sure which way is ultimately better. The bit-field is better to conserve memory as you are using 1 cell (4 bytes) vs. a 33 cell array (132 bytes) as a storage mechanism for player indexes. On the other hand, the array method may be less CPU expensive but it will obviously utilize more memory. PHP Code: ``` #define AddFlag(%1,%2)       ( %1 |= ( 1 << (%2-1) ) )#define RemoveFlag(%1,%2)    ( %1 &= ~( 1 << (%2-1) ) )#define CheckFlag(%1,%2)     ( %1 & ( 1 << (%2-1) ) )new g_Admin;new g_Bot;public client_putinserver(id){    if ( is_user_admin( id ) )    {        //An admin connected, add a bit to the g_Admin bitfield for this players id        AddFlag( g_Admin , id );    }    if ( is_user_bot( id ) )        AddFlag( g_Bot , id );}public client_disconnect(id){    if ( CheckFlag( g_Bot , id ) )    {        //bot disconnected        RemoveFlag( g_Bot , id );    }}public YourFunction(id){    if ( !CheckFlag( g_Admin , id ) )    {        //You are not an admin    }    if ( !g_Admin )         //There are no admins online!}  ```

Bugsy you can also do this: (i don't know how to put a % in a macro)

1 << value % 32
__________________
Bugsy
AMX Mod X Moderator
Join Date: Feb 2005
Location: NJ, USA
04-19-2009 , 16:47   Re: [INFO] Bitsums and Operators
#6

Quote:
 Originally Posted by joaquimandrade Bugsy you can also do this: (i don't know how to put a % in a macro) 1 << value % 32
Yes, either way works. Your method using modulus will make the 0 bitshift occur at 32 instead of 1 like my -1 method.

PHP Code:
``` #define AddFlag(%1,%2)        ( %1 |= ( 1 << (%2 % 32) ) )#define RemoveFlag(%1,%2)     ( %1 &= ~( 1 << (%2 % 32) ) )#define CheckFlag(%1,%2)      ( %1 & ( 1 << (%2 % 32) ) )  ```
__________________
Veteran Member
Join Date: Dec 2008
Location: Portugal
04-20-2009 , 05:44   Re: [INFO] Bitsums and Operators
#7

Quote:
 Originally Posted by Empowers Wow thx for Great TUT! Profiled: Code: ```date: Sun Apr 19 15:20:28 2009 map: de_dust type | name | calls | time / min / max ------------------------------------------------------------------- n | register_clcmd | 2 | 0.000019 / 0.000004 / 0.000015 p | array_test | 10 | 0.064196 / 0.006202 / 0.006642 p | bitsum_test | 10 | 0.029594 / 0.002811 / 0.003570 p | plugin_init | 1 | 0.000002 / 0.000002 / 0.000002 0 natives, 0 public callbacks, 3 function calls were not executed.``` Tested on this code: PHP Code: ``` #include new array[33]new bitsumpublic plugin_init() {    array[32] = false            bitsum &=  ~(1<<32)         register_clcmd("array","array_test")    register_clcmd("bitsum","bitsum_test")}public bitsum_test(){    for(new i;i<=1_000_000;i++)        if(bitsum & (1<<32))            continue;}public array_test(){    for(new i;i<=1_000_000;i++)        if(array[32])            continue;}  ``` Now I'm thinking should I swap arrays with bitsums in my plugins code. It would use less memory, but it will be harder to understand the code.
__________________
Empowers
BANNED
Join Date: Feb 2009
Location: Ukraine
 04-20-2009 , 05:52   Re: [INFO] Bitsums and Operators #8 Ok forget it man.. I can't talk with u
Veteran Member
Join Date: Dec 2008
Location: Portugal
04-20-2009 , 05:53   Re: [INFO] Bitsums and Operators
#9

Quote:
 Originally Posted by Empowers Ok forget it man.. I can't talk with u
Of course you can. But you need to
Quote:
 Read more carefully my post ;)
__________________
Exolent[jNr]
Veteran Member
Join Date: Feb 2007
Location: Tennessee
04-20-2009 , 08:10   Re: [INFO] Bitsums and Operators
#10

"continue" is never called because the if() statement never returns true.

Code:
```    array[32] = false

bitsum &=  ~(1<<32)```
__________________
No private work or selling mods.
Quote:
 Originally Posted by xPaw I love you exolent!

 Thread Tools Display Modes Hybrid Mode

 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 Forum Rules
 Forum Jump User Control Panel Private Messages Subscriptions Who's Online Search Forums Forums Home Server Discussion     Source Servers (SRCDS)     HL1 Servers (HLDS) AMX Mod X     News     Bug Reports     General     Off-Topic     Plugins         Suggestions / Requests         Approved Plugins         New Plugin Submissions         Unapproved/Old Plugins         Translation Request         High-Traffic Plugins             GunGame             UAIO (Ultimate All-In-One Plugin)             xREDIRECT             CSDM             AMX Super             RuneMod             Zombie Plague Mod             SuperHero Mod                 News                 Tech Support                 Scripting Help                 Off-Topic / General Chat                 Heroes                     Suggestions / Requests                     Approved Heroes                     New Submissions                     Unapproved/Old Heroes                         Module Heroes                     SuperHero Mod Stats - By 123                 (OLD) Bug Reports     Scripting         Scripting Help         Code Snippets/Tutorials         Module Coding     Donor Access SourceMod     News     General     Plugins         Plugins         Unapproved Plugins         Plugin/Gameplay Ideas and Requests         High-Traffic Plugins             SourceMod Anti-Cheat             Zombie:Reloaded             SourceBans / SourceBans++             VSH / Freak Fortress             Store             SM_Hosties             HLstatsX:CE     Scripting     Extensions     Snippets and Tutorials     Donor Access     Metamod: Source         Metamod:Source Plugins         Metamod:Source Questions         Coding MM:S Plugins & SM Extensions Hosted Stuff     Asherkin's Plugins         TFDodgeball         TF2Items         SteamTools     Bail's Plugins         CSDM         CS:S DM Off-Topic & Trash     Off-Topic     Trash

All times are GMT -4. The time now is 11:35.

 DMCA - Archive - Top