Home
Search
 
What's New
Index
Books
Links
Q & A
Newsletter
Banners
 
Feedback
Tip Jar
 
C# Helper...
 
XML RSS Feed
Follow VBHelper on Twitter
 
 
MSDN Visual Basic Community
 
 
 
 
 
TitleAnswer: KeyAscii And 223
Keywordsquick question answer, quiz answer, answer
Categories
 
1. What does this code do?

    The magic number 223 is 11011111 in binary so setting
        KeyAscii = KeyAscii And 223
    clears the 6th bit in KeyAscii.

    The code does this

        If KeyAscii > 96 And KeyAscii < 123
    The magic number 96 is 1 less than the ASCII value for "a" and 123 is 1 greater than the ASCII value for "z". Thus the code clears the 6th bit if the letter is between "a" and "z". Clearing the 6th bit happens to convert a lowercase letter into an uppercase letter.

    So this code as a whole converts lowercase letters into uppercase letters.

2. Is this a good idea?

    No. This code is obscure and unnecessarily confusing. It's also not internationally aware and doesn't handle Unicode.

3. Can you think of an alternative?

 
' Convert letters to uppercase.
Private Sub txtValue_KeyPress(KeyAscii As Integer)
    KeyAscii = Asc(UCase$(Chr$(KeyAscii)))
End Sub
 

    This code is easier to read and understand. It doesn't use magic numbers and anyone who understands the standard Chr$, UCase$, and Asc functions should be able to figure it out. The comment makes that easy.

    As Toby Bascom points out, "This converts *all* letters to upper case; not just a-z but also the umlauted German characters ä ö ü."

    You could probably make the code a little faster by testing whether KeyAscii is between Asc("a") and Asc("z") before making the conversion.

4. How could you improve the original code?

    For starters, add some comments! The original code I got this from used this comment:

    ' If KeyAscii is in range, then
    ' perform bit-wise comparison and assign result.
    

    This comment is technically correct and completely useless. It doesn't tell you what the goal is, how it is achieved, or what the magic numbers mean.

    The following version is better. It uses comments to make it clear what is happening. It uses constants to describe magic numbers.

 
' Convert letters to uppercase.
Private Sub txtValue_KeyPress(KeyAscii As Integer)
Const ASC_a As Integer = 97
Const ASC_z As Integer = 122
Const SIXTH_BIT_CLEAR As Integer = &HDF

    ' See if this is a lowercase letter.
    If (KeyAscii >= ASC_a) And (KeyAscii <= ASC_z) Then
        ' Clear the 6th bit to convert into uppercase.
        KeyAscii = KeyAscii And 223
    End If
End Sub
 

    Declaring SIXTH_BIT_CLEAR using hexadecimal at least tips experienced programmers off that this is not a normal number. It's something special such as a bit mask (as is the case here). It would be better if we could specify the value in binary (11011111) but that's not an option in Visual Basic.

5. Now is this a good idea?

    This is much better but it's still not a great idea. The code is still obscure and relies on the sneaky trick that clearing the 6th bit converts from lowercase into uppercase so it won't work if the character set changes.

    The original tip I saw touted this trick as faster than using Chr$, UCase$, and Asc. In fact, it is faster. In one informal test, the original version took approximately 0.00000077 seconds to convert a character into uppercase. The version using Chr$, UCase$, and Asc took about 0.00000340 seconds.

    However, the code is used in a KeyPress event handler so it executes when the user types a character. Unless your user can type a several thousand characters per second, the difference in speed isn't going to matter much.

    Amusingly the original tip also said to put the code in a subroutine if you need to use it in multiple TextBoxes. That roughly doubles the time. If you really need those extra microseconds, this is a bad idea.

Moral

Initially write your code in a straightforward way. Use comments, constants, and other good programming practices to make the code easy to understand.

Later, if you know you have a problem with the code's performance, you can optimize it. In this example, there will be no problem because the code is in a KeyPress event handler and the user's typing speed will make the tiny improvement in speed moot. Don't waste time optimizing code that is fast enough.

Get it working correctly first. Then optimize only where you know it is necessary. (This is an important theme in my book Bug Proofing Visual Basic).

As a final note, most software projects fail because they don't correctly do what they are supposed to do, not because they do the right thing too slowly!

Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.
  Updated