March Seventh 2008 From: Bob Zale, President PowerBASIC, Inc. PowerBASIC Gazette #59 ====================== Subject: Programming with BIT FIELD variables ============================================= Bit Field Variables =================== PowerBASIC offers a wide range of variable types. Signed. Unsigned. 8-bit, 16-bit, even 32-bit and 64-bit. But, sometimes, that just isn't enough. For example, there are many times when you only need to store a value for true/false or on/off... it takes just one bit to represent the value 0 or 1. Why waste a whole variable for that? If you need to represent the day of the week, you might use the values 1 to 7. Those particular values can be represented in just 3 bits. Why waste a regular variable for that, too? Well, it's now no longer necessary. Bit Field variables to the rescue! Use them to design your own custom variables, anywhere from 1-bit wide to a full 31-bits. You can pack these variables in a User-Defined Type or Union, one after another, to gain the very best in memory efficiency. You can use them for compatibility, too. They're common in C and C++. The Windows API uses them extensively. Even if you don't need them now, it's good to understand them... and good to know they'll be right at your fingertips the day you find you really need this new power. Bit Field variables come in two flavors, signed and unsigned. Just as with regular integer-class variables, the signed variety can be used to store both positive and negative values, while unsigned are restricted to just positive values. Internally, the signed versions use one bit for the sign, and the remaining bits for the numeric value, while the unsigned use all the bits for the value. Signed Bit Field variables are called SBIT variables, while the unsigned variety are simply called BIT variables. They are only valid as a member of a User-Defined TYPE or UNION, because they are tightly packed, one after another, in order to optimize for the very minimum amount of memory usage. This can be critically important when you create a large array of these data types. As I said earlier, BIT variables are custom variables -- you decide the size, and you decide the format. For example, "BIT * 1" defines a 1-bit unsigned variable which may take the value 0 or 1. The following table shows the range of values which may be stored in Bit Field variables of each possible size. The first two columns list the range for unsigned BIT variables, while the next two columns denote the range for the same size signed SBIT variables: 1 bit -->> 0 to 1 -1 to 0 2 bits -->> 0 to 3 -2 to +1 3 bits -->> 0 to 7 -4 to +3 4 bits -->> 0 to 15 -8 to +7 5 bits -->> 0 to 31 -16 to +15 6 bits -->> 0 to 63 -32 to +31 7 bits -->> 0 to 127 -64 to +63 8 bits -->> 0 to 255 -128 to +127 9 bits -->> 0 to 511 -256 to +255 10 bits -->> 0 to 1023 -512 to +511 11 bits -->> 0 to 2047 -1024 to +1023 12 bits -->> 0 to 4095 -2048 to +2047 13 bits -->> 0 to 8191 -4096 to +4095 14 bits -->> 0 to 16383 -8192 to +8191 15 bits -->> 0 to 32767 -16384 to +16383 16 bits -->> 0 to 65535 -32768 to +32767 17 bits -->> 0 to 131071 -65536 to +65535 18 bits -->> 0 to 262143 -131072 to +131071 19 bits -->> 0 to 524287 -262144 to +262143 20 bits -->> 0 to 1048575 -524288 to +524287 21 bits -->> 0 to 2097151 -1048576 to +1048575 22 bits -->> 0 to 4194304 -2097152 to +2097151 23 bits -->> 0 to 8388608 -4194304 to +4194303 24 bits -->> 0 to 16777215 -8388608 to +8388607 25 bits -->> 0 to 33554431 -16777216 to +16777215 26 bits -->> 0 to 67108863 -33554432 to +33554431 27 bits -->> 0 to 134217727 -67108864 to +67108863 28 bits -->> 0 to 268435455 -134217728 to +134217727 29 bits -->> 0 to 536870911 -268435456 to +268435455 30 bits -->> 0 to 1073741823 -536870912 to +536870911 31 bits -->> 0 to 2147483647 -1073741824 to +1073741823 Of course, you should use care. Just like so-called "regular" variables, if you try to assign a value to a Bit Field variable which is outside the legal range, you get undefined results. So, how are BIT variables defined? As mentioned earlier, they must be a part of a User-Defined TYPE. As the programmer, you get to define the size of the entire field, as well as the BIT variables which make up that field. Each field may be 1, 2, or 4 bytes in size, and there may be any number of these fields in a TYPE. You'll use the word BYTE, WORD, or DWORD to specify the field size: TYPE ByteParts Nybble1 as BIT * 4 in BYTE Nybble2 as BIT * 4 END TYPE In the above example, the phrase "in BYTE" specifies that the field is one byte in total size, and accessible through either of the two 4-bit nybbles. Each of the 4-bit nybbles can store a value in the range of 0 to 15. An alternative could be to use signed variables in a similar structure: TYPE ByteParts Nybble1 as SBIT * 4 in BYTE Nybble2 as SBIT * 4 END TYPE The only difference here is that each of the 4-bit nybbles can store a signed value, in the range of -8 to plus 7. It's really just that easy! What if you need a larger field? No problem... TYPE DWordParts Nybble1 as BIT * 4 in DWORD Nybble2 as BIT * 4 Nybble3 as BIT * 4 Nybble4 as BIT * 4 Nybble5 as BIT * 4 Nybble6 as BIT * 4 Nybble7 as BIT * 4 Nybble8 as BIT * 4 END TYPE Now, the phrase "in DWORD" tells us that the field is a total of four bytes in total size, and it's accessed through any one of the eight member nybbles. Remember, a User-Defined TYPE may contain one bit field, or many bit fields. You're the programmer, so you're in control! Let's say you need to separate a LONG INTEGER variable into its component parts, and you also need to maintain a number of true/false values as well. Here's a simple way to do just that: Type abcd Valu as BIT * 31 in DWORD Sign as SBIT * 1 Flag as BIT * 1 in BYTE Text as BIT * 1 Slot as BIT * 1 Coin as BIT * 1 Dart as BIT * 1 End Type In the above example, the entire TYPE is 5 bytes in size, consisting of seven member variables. You may have noticed that only 5 bits were used in the second bit field. It's perfectly acceptable to leave some bits unused if they're not needed. But be sure you never try to exceed the size... You simply can't fit 9 bits in 1 byte! How do you access BIT and SBIT variables? Just like any other member of a User-Defined TYPE: DIM Structure as abcd Structure.Coin = 1 Structure.Slot = 0 IF ISTRUE Structure.Coin THEN MSGBOX "We have a valid coin." END IF I hope it's now clear that bit field variables can greatly compress your data size. They can make more code self-documenting. They'll give you compatibility with certain "C" code, and assist with the Windows API. Regardless of the application, it's a powerful tool for the programmer... and found only in your favorite brand of BASIC! You can find a complete copy of the PowerBASIC Documentation on the PowerBASIC Web Site at: http://www.powerbasic.com/support/help/pbcc/index.htm http://www.powerbasic.com/support/help/pbwin/index.htm PowerBASIC Forums ================= Be sure to visit us soon on the web! Several months ago, we upgraded our forums to all new software! It's been wonderful. The new search function is amazing... all sorts of options to help you find just the programming information you need! The PowerBASIC Forums now sport over 275,000 contributions from good programmers just like you. They ask questions, they get answers, so can you. Just click... http://www.powerbasic.com/support/pbforums You know, just yesterday, we set a record on our forums. At 10:59 AM, 273 of our friends visited, all at the same time. Come join us right now? Take a look around and and see if we can break that record, too? We'd love to hear your questions... your answers... maybe even see a little of your latest code. So would others, and they'll respond! Lots more to follow on the web site... and the next Gazette! ==================================================================== Is your PowerBASIC Gazette Electronic Edition subscription coming to you at home or work? If you don't want to miss a single issue, why not subscribe from both email addresses? Send your subscription request to email@powerbasic.com and please include your name and all email addresses you'd like to add as well as your Zip or Postal Code. If you know someone else who would enjoy this newsletter please forward a copy to them so they can subscribe. ==================================================================== All contents Copyright (c) 2008-2009 PowerBASIC Inc All Rights Reserved. PowerBASIC, PB/CC, PB/DLL, PB/Win, PowerTREE, and PowerBASIC Forms are trademarks of PowerBASIC Inc. Other names are trademarks or registered trademarks of their respective owners. ==================================================================== PowerBASIC Gazette - Electronic Edition Volume 1 - Issue 59 PowerBASIC, Inc. (888) 659-8000 Sales 2061 Englewood Road (941) 473-7300 Voice Englewood, FL 34223 (941) 681-3100 Fax Visit us on the World Wide Web at www.powerbasic.com Email PowerBASIC Sales: sales@powerbasic.com This newsletter is only sent to e-mail addresses in our subscription list. If you have received this newsletter by mistake or no longer wish to receive it, please send a simple unsubscribe request to gazette@powerbasic.com with your name and zip/postal code. ====================================================================