![]() |
|
|
|
|
|
|
5
20th November 03:40
External User
Posts: 1
|
Replying to "Steve Laycock" since I cannot see his original post
Since I have very limited experience with using Delphi's built-in databases (I normally "roll my own"), I cannot help with queries/tables/filters etc but I may be able help with the bit-setting and bit-reading. First, this sort of scheme is normally used for binary data, ie things that are true/false. Eye colour is not one of these since eyes can be brown, green, grey, blue or any shade between. And hair colour is similar. The scheme can be used for values like Eyes-are-blue, Eyes-are-green, Eyes-are-brown, Gender-is-male etc. You are limited by the number of bits in the type you are using to store the data in. Remember 8 bits per byte. AFIK, currently the 32 bit longword/cardinal type is the largest available Delphi integer type, so you are limited to a maximum of 32 values. Using sets with their 128 maximum-values would give you more flexibility but your database may not support Delphi sets. In bit-setting, the bits available are all powers of 2: 2^0 (1), 2^1 (2), 2^2 (4), 2^3 (8) to 2^31 for a longword. The value 3 "overlaps" values 1 and 2, so using it takes up 2 bits of your integer. Assuming BitArray is an integer type and ecBlue (blue eyes) is a power of 2: To set ecBlue, use BitArray := BitArray or ecBlue. and to find out if the ecBlue bit is set, use something like HasBlueEyes := BitArray and ecBlue > 0; Storing data by bit-setting used to be popular when memory and disk-space was at a premium but its usefulness is now much less. As others have suggested, it is much simpler to using separate fields for the attributes. -- Henry Bartlett HABit utilities ( http://www.hotkey.net.au/~hambar/habit/ ) <SNIP> |
|
|
8
20th November 03:41
External User
Posts: 1
|
In article <YjRxb.31457$aT.24255@news-server.bigpond.net.au>, "Steve Laycock"
<slaycock@bigpond.net.au> writes: If you _must_ use that strategy (and I think that you're making things a bit complicated for little real gain) then you are moving into the area of Delphi sets. Sets are collections of ordinal values (each ordinal must be less than 256), and is normally implemented as a set of enumerated values. Enumerated values are of a type containing named values which are declared in a similar manner to an array constant. The names of the enumerated values by convention have a prefix of the initials of the type name ... type TWeekDays = (wdSunday, wdMonday, wdTuesday, wdWednesday, wdThursday, wdFriday, wdSaturday); Enumerated values are usually used as constants instead of using "magic numbers" (ie a number without any obvious meaning). Delphi allocates values from 0 upwards for the value of each enumerated value, so wdTuesday would have a value of 2. A set can be defined as ... TWeekDaySet = set of TWeekdays; .... and is assigned by specifying enumerated values between square brackets ... var OpenDays : TWeekDaySet; begin OpenDays := [wdMonday, wdWednesday, wdFriday]; Sets can be manipulated by various operators and functions such as +, -, >=, in, Include(), Exclude(). Now to your particular interest. Sets are implemented by Delphi as bits in a value. Each bit (from LSB == the first enumerated value) For up to 8 enumerated values in a set they are bits of a byte, for up to 16 values, bits of a word, etc. To use a set as the implemented item one must typecast the set ... var OpenDaysByte : byte; begin OpenDaysByte := byte(OpenDays). .... would reult in OpenDaysByte having bits 1, 3, and 5 set in the byte, ie a value of 42. And of course ... var SomeByte : byte; begin SomeByte := 40; if (wdWednesday in TOpenDaysSet(SomeByte)) then ..// "true" conditional. This is of course more coding that specifying what you have worked out as the equivalent values of setting bits, bur results in code clarity and no magic numbers. Enumerated values a very useful and can be used as array indices with the array type being declared as ... const WeekDayStr : array[TWeekDays] of string = ('Sunday', 'Monday', 'Tuesday', etc .... then ... OpenDaysStr := ''; for I := Low(TWeekDays) to High(TWekDays) do if I in OpenDaysSet then OpenDaysStr := OpenDaysStr + WeekDayStr[i] + ', '; if Length(OpenDaysStr) > 2 then SetLength(OpenDaysStr, Length(OpenDaysStr) - 2); Alan Lloyd alanglloyd@aol.com |
|