Results 1 to 12 of 12

Thread: First stuff for the new VB6 site

  1. #1

    Thread Starter
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    First stuff for the new VB6 site

    I wrote these articles today at work in my spare time. They'll be one of the most generic content on the site I'm working for, and it'd be nice if you can give comments and such before I put the site up (and I guess it might take time, these are just pure text files). Anyways, here they are as they currently are:


    Behind the binary numbers

    In my opinion, one of the most important things for a programmer to know are the numbers. If you can't handle math, you can't do very good stuff. Why? Well, you don't know what happens to the numbers, you don't really know the stuff happening "behind the scenes", unless you understand the numbers.

    Binary numbers are simple after you get used to them. Binary is also the way computer processes the data, even though this doesn't say all that much to a human. A byte consists of eight bits, bits that are binary. A byte can have a value between 0 - 255. But why? Lets have a few examples.

    00000001 - this is 1 in decimals. Quite simple.
    00000010 - this is 2 in decimals. How come?

    For humans, the smallest bit is in the right. The bits enlarge cumulatively from the smallest to biggest. Thus:

    00000100 - 4
    00001000 - 8
    00010000 - 16
    00100000 - 32
    01000000 - 64
    10000000 - 128

    When we add all these values together, we get 255. 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128. But how do we get these add-ups? Well, most people have guessed it already:

    00000011 - 3
    00000101 - 5
    11000000 - 192

    Now you should somewhat understand how binary values work. I hope you understand the relation to bytes, integers and longs as well


    Binarywise operators

    You might have heard of these operators before: And, Or and Xor. But what these actually do? As you can guess from the header, they have something to do with binary. I try to go as easy as one can go with them.

    First of all, lets have two example values:

    A = 11111000 - 248
    B = 00011111 - 31

    Now, lets play with A and B using these operators.

    And makes a comparison for active bits (1) and if both bits in the same values are active, they are left active. If they're not active, the resulting value has these bits turned off.

    A And B = 00011000 - 24

    Or works differently. It check for active bits and makes them active in both values.

    A Or B = 11111111 - 255

    Then we have Xor. It checks for difference and sets non-matching bits active and turns the others off. Thus:

    A Xor B = 11100111 - 231


    Then follows a summary:

    And:
    0 to 0, result is 0
    0 to 1, result is 0
    1 to 0, result is 0
    1 to 1, result is 1

    Or:
    0 to 0, result is 0
    0 to 1, result is 1
    1 to 0, result is 1
    1 to 1, result is 1

    Xor:
    0 to 0, result is 0
    0 to 1, result is 1
    1 to 0, result is 1
    1 to 1, result is 0


    I hope this is clear enough and the world of binaries opens to you


    Hex and their relation to binary

    I write a separate article about hex values, but I want to tell about the relation to binary values in this article. Hex values have 16 different numbers (the everyone's known decimal system has 10 different in comparison). These values are 0 - F (0 - 15). So, what is the relation to binaries? Lets take a look at number 255:

    Binary:
    11111111

    Hex:
    FF

    Can anyone see a similarity? If not, I'm going with an explanation. The lowest four bits are 1, 2, 4 and 8. When we add these together, we get 15. Someone might have a bell ringing at this point. So, we split both values into two pieces:

    Upper bits: 1111 - F
    Lower bits: 1111 - F

    The relation should be rather clear. Knowing this, it shouldn't be much of a trouble to convert values to hex format. There is only one question one might have: how do we make the upper bits (16, 32, 64 and 128) seem like the lower bits? Luckily, VB has something we can work with: operator \

    \ looks how many times a value fits within another. The lowest bit in the upper bits is 16. Thus, if we use \ 16 to the upper bits, we make them the same as the lower bits.

    So, to rip the bits:
    UpperBits = (ByteValue And &HF0) \ &H10
    LowerBits = ByteValue And &HF

    Wait wait wait a second! Why And? Well, we wanted to rip the active bytes and that is exactly what And is doing. Also, using hex values is much clearer (binarywisely thinking) than using decimals, because of the clear relation I told about before. Basically we ignore the bits we don't want to use and get the bits we want to.


    Bitshifting

    One thing missing from Visual Basic are the real bitshifting operators. Bitshifting is a rather simple operation:

    A = 01110000

    Result = A >> 1

    The code above moves bits to the right by one bit. Or, it would if the operator would exist in Visual Basic. The result of the above is:

    Result = 10111000

    As you can see, the bits moved to right and the active bits appeared from the left. This is how the operator works in C/C++

    A = 00001110

    Result = A << 1

    Result = 00011100

    This time active bits didn't appear, though the bits did move to the left as you could guess. Now we have only one question: how to imitate this behavior on Visual Basic?

    We're not completely without tools to work with. We have a nice operator: \. This is a very fast to execute in compiled code (and so are And, Or and Xor, if I didn't tell you) so it is almost as good as bitshifting operator. But you must do a bit more work to get the wanted results:

    By one bit to the right:
    Result = (A \ &H2) Or &H80

    Why Or? Well, we need to set the highest bit active. Hex 80 is the same as the highest bit.

    By two bits to the right:
    Result = (A \ &H4) Or &HC0

    &HC0? How come? &H80 + &H40 = &HC0. A = 10, B = 11, C = 12, D = 13, E = 14 and F = 15.

    Then how about shifting to the left? First of all, we must turn off the bits we don't want to move, to prevent making too big values. Then we simply use * to move the bits.

    By one bit to the left:
    Result = (A And &H7F) * &H2

    By two bits to the left:
    Result = (A And &H3F) * &H4

    Whenever you need to do bitshifting, I suggest to do it this way instead of making a separate function: calling a function is too slow task to do. Just comment your code when you do this so someone else can understand better what you're doing, too.


    Integers and Longs in VB

    One of the major problems with Visual Basic is that 16-bit (Integer) and 32-bit (Long) values within VB are always signed. This means, the highest bit is reserved for telling if a value is negative or not. This makes bitshifting a bit harder for these values. Luckily And, Or and Xor can skip this problem. Thus, with integers:

    IsHighestBitActive = (Value And &H8000) \ &H8000

    And with longs:

    IsHighestBitActive = (Value And &H80000000) \ &H80000000

    A more cheatty way to check if the highest bit is active:

    If Value < 0 Then HighestBitIsActive


    Hmm... I guess I've written quite a bit about binary by now. If you have questions to ask or suggestions to give, there is a page where you can find out how to contact me and links to places where you can get more help.


    ---

    End of the first article. I post the other one into separate message.

  2. #2

    Thread Starter
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654
    The Wonderful Hex

    If you've read the binary article, you might already know quite a bit about hex. Anyways, hexadecimal numbers are based to 16 numbers unlike the normal decimal system, which bases on 10 numbers. But why hexadecimals exist? To put it simply, they are easier to use and understand in programming than decimals.

    Here is a quick table to get started with:

    Code:
    0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
    0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
    At this point, I have to say one major note about hexadecimals: for computer, it is all the same how numbers are displayed to you or the user. It processes the numbers in binary, but for humans decimals and hexadecimals tell a whole lot more and this is the reason these formats are used. So however you view the numbers, only thing that matters for computer are the binary numbers.

    One of the most common thing about hex numbers is how to convert values into displayable hex strings and vice versa. I did write something related to this in the binary article, but I tell the basics here as well, along with some additional information.

    First major problem is with strings. You could use Chr$() or ChrW$() to add the resulting characters into a string and Asc or AscW together with Mid$() to get the character codes, but this is slow.

    The next problem are the character codes. After taking a look at character map, you might notice one interesting thing:

    Code:
    Code	Hex	Binary	Character
    48	30	00110000	0
    49	31	00110001	1
    50	32	00110010	2
    51	33	00110011	3
    52	34	00110100	4
    53	35	00110101	5
    54	36	00110110	6
    55	37	00110111	7
    56	38	00111000	8
    57	39	00111001	9
    58	3A	00111010	:
    59	3B	00111011	;
    60	3C	00111100	<
    61	3D	00111101	=
    62	3E	00111110	>
    63	3F	00111111	?
    64	40	01000000	@
    65	41	01000001	A
    66	42	01000010	B
    67	43	01000011	C
    68	44	01000100	D
    69	45	01000101	E
    70	46	01000110	F
    Character code &H30. See what it is in binary? 00110000 - why this is interesting? Well, the four lower bits are unactive. And the four lowest bits are just enough to fill them with hexadecimal information, because binary 1111 is 15, which is the biggest hexadecimal number.

    This doesn't resolve one thing though: how do we get "ABCDEF" instead of characters ":;<=>?" ? If you put any thought into it, you soon realise an easy solution for this.

    In any case, always when we want to prevent slow code (= string processing), we have to take a look into alternative methods. Fastest you could get are Long arrays, because 32-bit values are native to a modern processor. Well... we have 64-bit processors pushing through to the consumer market, but they have a very good 32-bit support. The problem is converting these arrays to strings and you need to use API to do this (CopyMemory aka RtlMoveMemory to be exact). So we'll have to say no to this, as I personally prefer pure VB code (you can take a look in the VBspeed article though if you want to learn the very fastest methods you can get with VB). So, the second best choise is to use byte arrays, because you can directly convert these into strings with pure VB code.

    One thing we need to notice with strings is that they're unicode. Two bytes per character. Thus the byte array must be two times the number of characters. Another thing related to the byte arrays is that the base index is 0. So instead of just placing the exact number of characters times two, you should decrease the value by one.

    Now it is the time for some code examples, so I can be more clear on what I mean. The code below should be very easy to follow, as it does byte to hex string conversion.

    VB Code:
    1. 'in a module (functions are fastest to call from a module)
    2. Public Function ByteToHexStr(ByVal Value As Byte) As String
    3.     'buffer to hold 2 characters (2 * 2 - 1) and variable A for loops
    4.     Dim Buffer(3) As Byte, A As Long
    5.     'these hold the ripped numbers
    6.     'as said before, longs are a bit faster to handle than bytes
    7.     Dim HighByte As Long, LowByte As Long
    8.     'first of all, rip the high bits and make them low bits
    9.     HighByte = (Value And &HF0) \ &H10
    10.     'then get the lower four bits
    11.     LowByte = Value And &HF
    12.     'check if the code is below the letters ABCDEF
    13.     If HighByte < &HA Then
    14.         'now add the character code for zero
    15.         HighByte = HighByte Or &H30
    16.     Else 'A, B, C, D, E or F
    17.         'at minimum, we get number 10 here, character code for A is 65, thus we add 55
    18.         HighByte = HighByte + 55
    19.     End If
    20.     'now the same as above for the lower four bits
    21.     If LowByte < &HA Then
    22.         LowByte = LowByte Or &H30
    23.     Else
    24.         LowByte = LowByte + 55
    25.     End If
    26.     'now assign these to the byte array
    27.     Buffer(0) = HighByte
    28.     Buffer(2) = LowByte
    29.     'and then convert to a string and return it
    30.    ByteToHexStr = Buffer
    31. End Function


    Then you probably like to do a quick test. Thus:

    VB Code:
    1. 'in a form
    2. Private Sub Form_Load()
    3.     Dim TestValue As Byte
    4.     TestValue = 255
    5.     MsgBox "Number '" & TestValue & "' in hex is '" & ByteToHexStr(TestValue) & "'"
    6.     Unload Me
    7. End Sub


    Now that we have done it this way, how about the other way around? Maybe this can be a matter for yourself to figure out, now that you saw quite a tip with the code above. Also, you have a challenge doing the same function for Integer and Long values, because they're signed data types, whereas byte is unsigned (= can't be negative). In the other hand, I do provide more advanced functions to play with elsewhere on the site.

    Anyways, I hope this all clear up the mess considering hexadecimal values in your mind and you learned something from this

    One last note in the end: the code sample above is fast once you compile the program.

    ---

    There. All (constructive) feedback is welcome

  3. #3
    Frenzied Member Jmacp's Avatar
    Join Date
    Jul 2003
    Location
    UK
    Posts
    1,959
    Excellent. I think a lot of sites are missing these fundamentals. Keep up the good work.

  4. #4
    Addicted Member
    Join Date
    Aug 2004
    Posts
    176
    under the topic "binarywise operators" why have u mentioned only three operators?
    why have the rest been left out?
    or r these the only ones u r interested in.

  5. #5
    Banned dglienna's Avatar
    Join Date
    Jun 2004
    Location
    Center of it all
    Posts
    17,901
    could have mentioned OCTAL numbers, a step in between binary and hex. They use 3 bits for each digit. They were the basis of very early computers, and I had to learn to calculate the byte in each base system for a value. Really burned it into my memory.

    Good articles. Maybe you could have used a few more VB examples, using API's that require HEX numbers, or that have constants that are hexidecimal.


  6. #6

    Thread Starter
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654
    In VB, there is no much use for octals and I have no previous experience on them. I want to keep the articles somewhat practical

    Another thing is that I want to prevent API when it isn't necessary. Also, what API takes in hexadecimal strings? If you meant this:

    VB Code:
    1. Const CONSTANT = &H1
    2. Const CONSTANT = 1
    3.  
    4. Const CONSTANT = &H20
    5. Const CONSTANT = 32
    6.  
    7. 'these make no difference, they are the same in compiled code

    flair: it would've been good if you mentioned what other operators I should have told about. The only I could have mentioned (that comes to my mind at the moment) is Not.

  7. #7
    Banned dglienna's Avatar
    Join Date
    Jun 2004
    Location
    Center of it all
    Posts
    17,901
    Octal is bits 421 to represent 0-7 you just take 3 bits at a time instead of 4 for hexidecimal. Just more work for college students back when I learned it. Not so years later in DP class. Everyone had calcuators and used them for conversion.



  8. #8

    Thread Starter
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654
    Two more articles:

    Byte Arrays versus Strings

    You know how handy Visual Basic's strings are: you can play with them easily, you don't need to define their size, just add more stuff to them when you want to. The problem with this? The speed. They're very slow to handle, even though they're very easy to use.

    What would be an alternative method? As you can guess from the header, byte arrays. But when and how should they be used? Lately I've started to use byte arrays a lot in the internal code, just because of the speed they provide in compiled code. Strings can get into many copies in memory at the time, but byte array stays where it is. The only time it might be automatically moved in memory is when you resize it a lot bigger. But how does one use them?

    VB Code:
    1. 'in a form: add a command button
    2. Private Sub Command1_Click()
    3.     Dim Buffer() As Byte, Temp As String
    4.     Temp = "This is a string"
    5.     Buffer = Temp
    6.     MsgBox Buffer
    7.     MsgBox "Character #1: " & Buffer(0) & " " & Buffer(1)
    8.     MsgBox "Character #2: " & Buffer(2) & " " & Buffer(3)
    9. End Sub

    Interesting? You can copy strings to variable length byte arrays. You can also copy any byte array into a string (unless it is a fixed length string). You might also notice that with byte array, you don't need to use Asc and Mid$ together to get a character code: you can just directly change characters as you like. The only problem you have is that you can't freely add characters to the end of the byte array, you need to resize it. How?

    VB Code:
    1. 'in a form: add a command button
    2. Private Sub Command2_Click()
    3.     Dim Buffer() As Byte
    4.     ReDim Preserve Buffer(23)
    5.     Buffer(0) = vbKeyI
    6.     Buffer(2) = vbKeySpace
    7.     Buffer(4) = vbKeyL
    8.     Buffer(6) = vbKeyI
    9.     Buffer(8) = vbKeyK
    10.     Buffer(10) = vbKeyE
    11.     Buffer(12) = vbKeySpace
    12.     Buffer(14) = vbKeyB
    13.     Buffer(16) = vbKeyY
    14.     Buffer(18) = vbKeyT
    15.     Buffer(20) = vbKeyE
    16.     Buffer(22) = vbKeyS
    17.     MsgBox Buffer
    18. End Sub

    One thing about ReDim: you should always use it in the Preserve mode, except if you are not filling the array with values and you want each value in the array to be zero. Yes, ReDim clears every byte in the byte array and this is what makes it slower than Preserve.

    You might be wondering why we are using only every other byte in the byte array. The reason for this is simple: VB strings are Unicode. They take up two bytes in memory. But because of historical reasons, VB controls do not support Unicode and you can see only garbage when you pass a string to them. But I tell more about this in the Unicode article.

    You might also have noticed that the byte arrays first item has index 0. You could define the array like this:

    VB Code:
    1. ReDim Preserve Buffer(1 To 24)

    But then you'd lose some speed, because zero based arrays are faster to handle.


    Passing Byte Arrays to API instead of Strigs

    There is a small problem when using API and strings: strings get automatically converted to ANSI format when passed to an API function. This slows down using API. Surprisingly only a few people have thought about passing a byte array instead of a string to API. There are a few rules to follow though:

    - ANSI strings have only one byte per character, thus there is no point converting a string to byte array, unless you're calling API many times
    - the last byte in the array must be zero, unless you can tell the API how many bytes/characters the array has
    - some API calls take Unicode strings: with these it is very advantageous to use byte arrays than strings, because you'd have to use StrConv to the string to get proper unicode results because of the automatical ANSI conversion!
    - with Unicode you have to have two zero bytes in the end of the array, unless the API call does take a length


    But... how to use byte arrays instead of strings? Here is some pseudocode:

    VB Code:
    1. Private Declare Function GiveMeAString Lib "system32" (ByVal MyString As String) As Long

    You'd use this API like this:

    VB Code:
    1. Result = GiveMeAString(String)


    To convert this for byte arrays, you need to do two changes. One to the API call, and to the way you call the API:

    VB Code:
    1. Private Declare Function GiveMeAString Lib "system32" (ByVal MyArrPtr As Long) As Long
    2.  
    3. Result = GiveMeAString(VarPtr(ByteArray(0)))

    This API, if it were real, would require that the last byte in the array is zero, or it'd read memory until it finds a zero byte. Thus you are likely to get errorneus results without it.


    What StrConv actually does?

    One useful function in VB is StrConv and you probably need to use it sooner or later. If you read a text file into a byte array, then you'd have to convert it using StrConv, because the file is likely to be in ANSI format. Though, I really recommend to convert stuff to strings only when you're trying to display them. Like, when you're passing the text file into a textbox:

    VB Code:
    1. 'if you want to test, uncomment the lines below
    2. 'Dim FileBuffer() As Byte
    3. 'ReDim Preserve FileBuffer(1)
    4. 'FileBuffer(0) = 65  [ A ]
    5. 'FileBuffer(1) = 66  [ B ]
    6.  
    7. Text1.Text = StrConv(FileBuffer, vbUnicode)
    8. Text2.Text = FileBuffer

    What StrConv actually does above, is that it adds a zero byte after each byte. It doesn't analyze the given variable at all or check if it is Unicode already.

    VB Code:
    1. FileBuffer = StrConv(Text1.Text, vbFromUnicode)
    2. 'uncomment the following lines if you want to do testing
    3. 'MsgBox FileBuffer(0) & " " & FileBuffer(1)
    4. 'FileBuffer = Text1.Text
    5. 'MsgBox FileBuffer(0) & " " & FileBuffer(1)

    This does the same thing to other way: it skips every other byte. If there is Unicode information, it loses it. If you do this to an ANSI string, you lose every other character. So again, StrConv doesn't check if the string is ANSI already; it couldn't detect that anyways, because it is impossible to programmatically tell if some data is Unicode or not.

    However things are, you shouldn't use StrConv unless you really have to, as it does give an additional slow down (it is pretty fast for a string function though).


    Working with Byte Arrays

    You soon notice the problem with byte arrays: you have to do everything by yourself. VB has a lot of string functions to work with, such as Left$, Mid$, Right$, InStr, Split, Replace$, Join, StrReverse, String$... there are no equivalents for byte arrays. This means you have to code the wanted functionality by yourself.

    Luckily, I've done various functions which I have included in the codebank of this site, so you don't need to bother doing the very basic functions. Most of them are faster than their equivalent string functions in the compiled application.

    Anyways, the basic method of working with byte arrays is to loop through the array and edit it as the code goes on. Sometimes you might be forced to first make a Long table array containing locations you have found by looping, then resize the array to the new size and then start copying stuff within the array with the help of the Long array. You need to do this because the arrays do not resize automatically and calling ReDim continuously is inefficient. Also, doing byte array editing requires a lot of brain work and this is also why I've made ready-to-use functions for many basic needs one might have. Surprisingly, this way of working has the most similarities to C/C++ coding and coders who are familiar with the language might like this way of coding a lot better - especially because this gives VB the wanted speed.


    At the moment, this is it. I might do some additions to this article later on, because I have a feeling I didn't write this out as well as I should have. I hope this is good enough to get started with the byte array way of thinking

    ---

    And then one more... which is shortest this far.

  9. #9

    Thread Starter
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654
    Option Explicit and variables

    One of the things you should always include in the beginning of every form, module and class module is Option Explicit. This forces you to declare (Dim) your variables. Besides you have your variables in the correct format instead of them being Variant, you get rid of bugs which happen because of typos. For example:

    VB Code:
    1. 'in a form: add a command button
    2. Private Sub Command1_Click()
    3.     Dim Variable As String
    4.     Varlable = "It works"
    5.     MsgBox Variable
    6. End Sub

    If you don't have Option Explicit, you see an empty message box. If you use Option Explicit, you get an error because you haven't declared Varlable and you then find out you have made a typo.

    Besides using Option Explicit, you should always define correct datatypes for whatever purpose you are using them. The five most common datatypes you need to use are Boolean, Byte, Date, Long and String. You might also want to use Integer when dealing with functions that return a 16-bit number. The only time you might want to use Variant is to use its 64-bit Decimal subtype, which can hold much bigger values than Long.

    Also, you shouldn't use wrong datatypes or use different datatypes with eachother except if you're trying to view something visually. This lets you get out of silly errors you might get otherwise, for example:

    VB Code:
    1. 'in a form: add a command button
    2. Private Sub Command2_Click()
    3.     Dim Test As String
    4.     Test = 1
    5.     Test = Test + Test
    6.     MsgBox Test
    7. End Sub

    You might expect to get 2 as a result. Instead you get 11. Thus: never use the wrong datatype! There is one more reason to this: it is faster to use the correct datatype. And when using the correct datatypes, you are less likely to get hard-to-debug compiled program errors in the cases you have turned the advanced optimizations on (which really do speed up the program).


    Hopefully this is enough for this matter. Will write more if I happen to bounce to something.

    ---

    And as told before, feedback is welcome. I guess these articles aren't just as good as the first ones. Just a feeling.

  10. #10
    G&G Moderator chemicalNova's Avatar
    Join Date
    Jun 2002
    Location
    Victoria, Australia
    Posts
    4,246
    Hardly ever see anyone explain the Preserve Keyword. Alot of people ask questions about it when we try and help them (when the help involves arrays).

    Keep it up Merri..

    Phreak

    Visual Studio 6, Visual Studio.NET 2005, MASM

  11. #11
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263
    Merri - very nice...

    I worship binary - our big $$ product here is a student scheduling algorithm - classes and study halls for students. We've been working that algorithm for about 20 years now. We represent the days of the week in a 11111 bit value - semesters in 1111 bit value - conflicts are checked with AND - stuff like that.

    A point I love to make when showing people BINARY and operators is that "x and 1" will be true only for ODD NUMBERS.

    Another point is that when the "high-order" bit is on, the value might appear negative in VB - signed vs unsigned interger stuff. I've noticed in posts that the negative value scares people.

    I personally like to use binary and not hex values in code - giving myself a series of CONSTANTS for each bit makes it easy to keep track of nibble, byte and word boundaries.

    VB Code:
    1. Const Bit$0 as Long = 1
    2. Const Bit$1 as Long = 2
    3. ...all the way up to 31

    Another point I like to make to those I'm teaching is that values like 255 are "all bits on" and make them notice that it's the next bit (in this case 256) with 1 subtracted from it.

    I'm not sure I understand the need for \ operator in a bit shift.

    When bit shifting you always use a power of 2, so / works fine - right? And with all the VARIABLES careful DIM's as LONG, remainders are not possible...

    Since it's you, it's probably a speed issue

    The concept of MASKING is important in bit shifting - here's something I posted a while ago to help someone who was doing "floating" point division with MOD to find the RGB parts of a color...

    Here is a snipet from something I posted a few months ago - about bitshifting and bit masking. Bitshifting down requires division - bitshifting up requires multiplication. Masking makes sure that you only keep bits you want.

    Division will move highorder to loworder.

    HTH...

    Short lesson - let's say we have two-bit colors only, so we need only 6 bits for the whole representation. Each two-bit area can have 0 (00), 1 (01), 2 (10) or 3 (11) turned on (the parens hold the BINARY value). So lets say I have RGB of 3, 2, 3 - that would be:

    111011 (see the 11, 10 and 11 - right?)

    I want just the G portion - the bit mask of 001100 will bring that through:

    111011 (the RGB)
    001100 (the mask)
    --------- (AND the values)
    001000 (the G portion by itself).

    Now, I want to bring it on down to a two-bit value (the value right now is decimal 8).

    I divide by 4 (000100) - this being the low bit position that I want to shift from.

    8 / 4 = 2 - or in binary

    001000 (the G value of 8)
    000100 (the bit pivot spot)
    divide these - yields...

    000010 (the "10" G value shifted down to the two-bit area).

    And of course "10" in binary is the decimal 2...

    Hope this makes sense.

    Also, if you want to change the bits to the opposite settings, the NOT operator does that.

    new value = NOT old value AND MASK

    000010 (the G value of 2)
    111101 (the NOT of the G VALUE - note that we switch all bits to opposite settings - even bits we were not interested in).

    BTW, the decimal value of this ugly mess is negative, because the "high-order bit is the sign bit...

    We get ugly high-order bits switched - we were looking to only NOT the two low-order bits.

    111101 (the UGLY NOT of the G value)
    000011 (AND'ing with the MASK of just the low-order two bits
    --------- (AND the values)
    000001 (comes through with just the two bits we were looking to reverse).

  12. #12

    Thread Starter
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654
    Yup, \ is two times faster than /. I use / only when I'm forced to use datatypes such as Currency or Single, or if I otherwise have to play with the digits (0,764 and so on).

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width