tags:

views:

109

answers:

3

Hello!

Could you please tell why the Asc() function returns incorrect result?

    Dim TestChar = Chr(128)
    Dim CharInt = Asc(TestChar) ' this is a mistake on Windows 7 x64. Asc(TestChar) returns 136 instead of 128

I executed this code on another computer and the result was 128.

Thanks.

+5  A: 

Your computer is using a different default code page.

The Asc function uses the system's current ANSI code page.
The Chr function simply casts the value to char. (Unless it's > 255)

SLaks
I wouldn't be so sure if this is the cause, because .NET generally always uses Unicode. Unless this is some retardation they carried over from VB6, of course. Would be another good reason for *VB.NET not to exist.*
Matti Virkkunen
@Matti: Yes, this is from VB6.
SLaks
Surely this can't be the whole story? `Asc` uses the current ANSI code page, but so does `Chr`: it converts an ANSI code-point number into a character (I think this is best called a *conversion* not a *cast*). So I believe `Asc(Chr(X))` would always return X? I've tried Alexander's snippet with Chinese code page, and `Asc(TestChar)` is 128. Perhaps in fact Alexander was running `Asc` with one code page and then later - or on another computer - `Chr` with another code page?
MarkJ
@MarkJ: `Chr` does a standard type-cast. (Unless it's `> 255`) Look at it in Reflector.
SLaks
@SLaks. To me this C# expression is a cast: `(char) 136`. It returns the Unicode character `U+0088` i.e. decimal 136. In VB `ChrW(X)` also uses Unicode. `char(X)` or `ChrW(X)` return a 2-byte character variable: if you look at the memory in a debugger you see the value X as a 2-byte unsigned integer. That's not true with VB's `Chr`. For example `Chr(136)` on code page `Latin-1 1252` returns `^` which is Unicode `U+02C6` or in decimal `710`. On `Arabic 1251` `Chr(136)` returns the Euro symbol `€` Unicode `U+20AC` decimal `8364`. Chr is the inverse of Asc.
MarkJ
@SLaks again. To summarise the last comment. If `(char) X` can be called a standard type-cast, then `Chr(X)` surely can't be called a standard type-cast, because it has different behaviour?
MarkJ
@MarkJ: Check Reflector. It has the same behavior for characters that are `< 255`. **EDIT** : I take that back. It has uses a cast for `< 128`.
SLaks
@SLaks. OK, that makes sense. I think `<128` is the same on all code pages and is the same as the Unicode values. By the way I did actually *run* the tests in my comments so I wasn't that concerned to look in Reflector. I still think the code snippet in Alexander's question can't be the whole story, but he seems to be happy...
MarkJ
+1  A: 

I just tried this exact code on Windows 7 x64 with Visual Studio 2010 and got the expected value of 128. I tried mixing options (Infer, explicit, etc ...) and the value remains the same. Can you provide some more details to help track this down?

Sub Main()
    Dim TestChar = Chr(128)
    Dim CharInt = Asc(TestChar)
    Console.WriteLine(CharInt)
    Stop
End Sub
JaredPar
+1  A: 

The problem was that I used the different default code page. I changed it into the English and code works fine. Thank you!

Alexander