Difference between revisions of "Bitwise Operations"

From SphereWiki
Jump to: navigation, search
m (Converting from decimal to binary and from binary to decimal)
Line 1: Line 1:
Bitwise operations are used to perform an action on the bits (the 1's and 0's) of a number.  Understanding what bitwise operators do requires you to understand how to convert from decimal to binary and from binary to decimal.
+
Bitwise operations are used to perform an action on the bits (the 1's and 0's) of a number.
  
 
In this article a "binary" formatted number (which represents the "bits" of a number) will be written with a <sup>2</sup>... and a decimal number with a <sup>10</sup>
 
In this article a "binary" formatted number (which represents the "bits" of a number) will be written with a <sup>2</sup>... and a decimal number with a <sup>10</sup>
  
 +
==Limitations==
 +
 +
In Sphere, numbers are stored in something called a "DWORD".  The largest number a DWORD can store is constrained by the fact that a DWORD is 32 bits wide. That means the largest number it can store is 2^32-1.
 +
 +
* In Binary that's 11111111111111111111111111111111.
 +
* In Hex it's FFFFFFFF.
 +
* In Decimal that's 4294967295.
 +
 +
To store a 'signed' number in a DWORD (in other words, a number that can be positive or negative), the first bit is used to indicate the sign (a 1 is negative).  Which means the largest 'signed' positive number is 2^31-1
 +
 +
* In Binary that's 01111111111111111111111111111111.
 +
* In Hex it's 7FFFFFFF.
 +
* In Decimal that's 2147483647.
 +
 +
In sphere script language, the EVAL function outputs a signed DWORD, and the UVAL outputs an unsigned DWORD.
 +
 +
[FUNCTION Mathtest]
 +
LOCAL.Number0=2147483647
 +
LOCAL.Number1=4294967295
 +
LOCAL.Number2=8589934588
 +
SERV.LOG eval0=<EVAL <LOCAL.Number0>> eval1=<EVAL <LOCAL.Number1>> eval2=<EVAL <LOCAL.Number2>>
 +
SERV.LOG uval0=<UVAL <LOCAL.Number0>> uval1=<UVAL <LOCAL.Number1>> uval2=<UVAL <LOCAL.Number2>>
 +
 +
The output of this test is:
 +
 +
13:37:(test.scp,10)eval0=2147483647 eval1=-1 eval2=-4
 +
13:37:(test.scp,11)uval0=2147483647 uval1=4294967295 uval2=4294967292
 +
 +
Notes:
 +
 +
* The output is limited to align with the limitation of the DWORD itself.
 +
* Since there are 32 "bits" in a DWORD, there can only be 32 flags in a set.
 +
* Be careful when manipulating flags using EVAL, because the 32nd flag could get lost.
 +
 +
==Flags==
 +
 +
In the Sphere server, quite a few concepts are implemented using "flags".  You can see examples of flags being defined in the Sphere.ini file, or the sphere_defs.scp files.  For example:
 +
 +
[DEFNAME attr_flags]
 +
attr_identified      01
 +
attr_decay            02
 +
attr_newbie          04
 +
attr_move_always      08
 +
attr_move_never      010
 +
attr_magic          020
 +
attr_owned          040
 +
attr_invis          080
 +
attr_cursed        0100
 +
attr_cursed2        0200
 +
attr_blessed        0400
 +
attr_blessed2      0800
 +
attr_forsale      01000
 +
attr_stolen        02000
 +
attr_can_decay    04000
 +
attr_static        08000
 +
attr_exceptional  010000
 +
attr_enchanted    020000
 +
attr_imbued      040000
 +
attr_questitem    080000
 +
attr_insured    0100000
 +
attr_nodrop      0200000
 +
attr_notrade    0400000
 +
attr_lockeddown  0800000
 +
attr_secure    01000000
 +
 +
Notice a pattern?  Let's tip it on it's side and chart the first 8 flags:
 +
 +
{|border=1 cellpadding=5
 +
|-
 +
|Flag Name:    ||  attr_invis||  attr_owned||  attr_magic||attr_move_never||attr_move_always||  attr_newbie||  attr_decay||attr_identified
 +
|-
 +
|Binary Number: ||    10000000||    01000000||    00100000||      00010000||        00001000||    00000100||    00000010||      00000001
 +
|-
 +
|Hex Number:    ||        080||        040||        020||            010||              08||          04||          02||            01
 +
|-
 +
|Decimal Number:||        128||          64||          32||            16||              8||            4||          2||              1
 +
|}
 +
 +
==The OR Operator (inclusive OR)==
 +
==The AND Operator==
 +
==The XOR Operator (exclusive OR)==
 +
==The NOT Operator==
 +
==Left and right shift==
 +
 +
 +
 +
 +
<!--
 
==Converting from decimal to binary and from binary to decimal==
 
==Converting from decimal to binary and from binary to decimal==
  
Line 62: Line 150:
 
# Therefore, the negative binary number 1111111111010011<sup>2</sup> is equal to the decimal number -45<sup>10</sup>
 
# Therefore, the negative binary number 1111111111010011<sup>2</sup> is equal to the decimal number -45<sup>10</sup>
  
==The OR Operator (inclusive OR)==
+
-->
==The AND Operator==
 
==The XOR Operator (exclusive OR)==
 
==The NOT Operator==
 
==Left and right shift==
 

Revision as of 22:46, 28 November 2013

Bitwise operations are used to perform an action on the bits (the 1's and 0's) of a number.

In this article a "binary" formatted number (which represents the "bits" of a number) will be written with a 2... and a decimal number with a 10

Limitations

In Sphere, numbers are stored in something called a "DWORD". The largest number a DWORD can store is constrained by the fact that a DWORD is 32 bits wide. That means the largest number it can store is 2^32-1.

  • In Binary that's 11111111111111111111111111111111.
  • In Hex it's FFFFFFFF.
  • In Decimal that's 4294967295.

To store a 'signed' number in a DWORD (in other words, a number that can be positive or negative), the first bit is used to indicate the sign (a 1 is negative). Which means the largest 'signed' positive number is 2^31-1

  • In Binary that's 01111111111111111111111111111111.
  • In Hex it's 7FFFFFFF.
  • In Decimal that's 2147483647.

In sphere script language, the EVAL function outputs a signed DWORD, and the UVAL outputs an unsigned DWORD.

[FUNCTION Mathtest]
LOCAL.Number0=2147483647
LOCAL.Number1=4294967295
LOCAL.Number2=8589934588
SERV.LOG eval0=<EVAL <LOCAL.Number0>> eval1=<EVAL <LOCAL.Number1>> eval2=<EVAL <LOCAL.Number2>>
SERV.LOG uval0=<UVAL <LOCAL.Number0>> uval1=<UVAL <LOCAL.Number1>> uval2=<UVAL <LOCAL.Number2>>

The output of this test is:

13:37:(test.scp,10)eval0=2147483647 eval1=-1 eval2=-4
13:37:(test.scp,11)uval0=2147483647 uval1=4294967295 uval2=4294967292

Notes:

  • The output is limited to align with the limitation of the DWORD itself.
  • Since there are 32 "bits" in a DWORD, there can only be 32 flags in a set.
  • Be careful when manipulating flags using EVAL, because the 32nd flag could get lost.

Flags

In the Sphere server, quite a few concepts are implemented using "flags". You can see examples of flags being defined in the Sphere.ini file, or the sphere_defs.scp files. For example:

[DEFNAME attr_flags]
attr_identified       01
attr_decay            02
attr_newbie           04
attr_move_always      08
attr_move_never      010
attr_magic           020
attr_owned           040
attr_invis           080
attr_cursed         0100
attr_cursed2        0200
attr_blessed        0400
attr_blessed2       0800
attr_forsale       01000
attr_stolen        02000
attr_can_decay     04000
attr_static        08000
attr_exceptional  010000
attr_enchanted    020000
attr_imbued       040000
attr_questitem    080000
attr_insured     0100000
attr_nodrop      0200000
attr_notrade     0400000
attr_lockeddown  0800000
attr_secure     01000000

Notice a pattern? Let's tip it on it's side and chart the first 8 flags:

Flag Name: attr_invis attr_owned attr_magic attr_move_never attr_move_always attr_newbie attr_decay attr_identified
Binary Number: 10000000 01000000 00100000 00010000 00001000 00000100 00000010 00000001
Hex Number: 080 040 020 010 08 04 02 01
Decimal Number: 128 64 32 16 8 4 2 1

The OR Operator (inclusive OR)

The AND Operator

The XOR Operator (exclusive OR)

The NOT Operator

Left and right shift