4

Why does the VB expression

Asc(ChrB(128) & ChrB(0))

yield 63 and not 128?

Recently, I've been looking at Visual Basic's InputB function for reading binary data. According to the help system, these B-suffixed functions are for use with "byte data" in text files and strings.

In VB, a single character in a string occupies not one but two bytes. For instance, the function call Input(1, #fnum) returns a two-byte string. In contrast, however, InputB(1, #fnum) returns a one-byte string (or "half" a character).

Traditional ASCII / ANSI characters are contained within a single byte. If you used InputB(1, #fnum) to read an ASCII / ANSI character into the first "half" of a string character and filled the second half with a "zero" byte using ChrB(0) then it should stand to reason that the resulting two-byte character would be identical to the result obtained using the ordinary Input(1, #fnum) instead.

In fact, that is largely what happens. It's only when you hit certain character codes, such as 128, that things go awry.

Consider the following code, for example. To avoid all the file handling code, I've used AscB in place of InputB.

Dim c1 As Integer
Dim c2 As Integer
Dim i As Integer

Debug.Print "Code #1", "Code #2"
For i = 0 To 255
    c1 = Asc(Chr(i))
    c2 = Asc(ChrB(i) & ChrB(0))
    Debug.Print c1, c2
Next i

The output is below.

All's well until we reach 128. From there to 159, c1 and c2 are sometimes identical, as expected, but other times not. When they're not, c2 is always 63. From 160 upwards, the output is again well behaved.

Code #1       Code #2
 0             0 
 1             1 
 2             2 
 3             3 
 4             4 
 5             5 
 6             6 
 7             7 
 8             8 
 9             9 
 10            10 
 11            11 
 12            12 
 13            13 
 14            14 
 15            15 
 16            16 
 17            17 
 18            18 
 19            19 
 20            20 
 21            21 
 22            22 
 23            23 
 24            24 
 25            25 
 26            26 
 27            27 
 28            28 
 29            29 
 30            30 
 31            31 
 32            32 
 33            33 
 34            34 
 35            35 
 36            36 
 37            37 
 38            38 
 39            39 
 40            40 
 41            41 
 42            42 
 43            43 
 44            44 
 45            45 
 46            46 
 47            47 
 48            48 
 49            49 
 50            50 
 51            51 
 52            52 
 53            53 
 54            54 
 55            55 
 56            56 
 57            57 
 58            58 
 59            59 
 60            60 
 61            61 
 62            62 
 63            63 
 64            64 
 65            65 
 66            66 
 67            67 
 68            68 
 69            69 
 70            70 
 71            71 
 72            72 
 73            73 
 74            74 
 75            75 
 76            76 
 77            77 
 78            78 
 79            79 
 80            80 
 81            81 
 82            82 
 83            83 
 84            84 
 85            85 
 86            86 
 87            87 
 88            88 
 89            89 
 90            90 
 91            91 
 92            92 
 93            93 
 94            94 
 95            95 
 96            96 
 97            97 
 98            98 
 99            99 
 100           100 
 101           101 
 102           102 
 103           103 
 104           104 
 105           105 
 106           106 
 107           107 
 108           108 
 109           109 
 110           110 
 111           111 
 112           112 
 113           113 
 114           114 
 115           115 
 116           116 
 117           117 
 118           118 
 119           119 
 120           120 
 121           121 
 122           122 
 123           123 
 124           124 
 125           125 
 126           126 
 127           127
 128           63 
 129           129 
 130           63 
 131           63 
 132           63 
 133           63 
 134           63 
 135           63 
 136           63 
 137           63 
 138           63 
 139           63 
 140           63 
 141           141 
 142           63 
 143           143 
 144           144 
 145           63 
 146           63 
 147           63 
 148           63 
 149           63 
 150           63 
 151           63 
 152           63 
 153           63 
 154           63 
 155           63 
 156           63 
 157           157 
 158           63 
 159           63 
 160           160 
 161           161 
 162           162 
 163           163 
 164           164 
 165           165 
 166           166 
 167           167 
 168           168 
 169           169 
 170           170 
 171           171 
 172           172 
 173           173 
 174           174 
 175           175 
 176           176 
 177           177 
 178           178 
 179           179 
 180           180 
 181           181 
 182           182 
 183           183 
 184           184 
 185           185 
 186           186 
 187           187 
 188           188 
 189           189 
 190           190 
 191           191 
 192           192 
 193           193 
 194           194 
 195           195 
 196           196 
 197           197 
 198           198 
 199           199 
 200           200 
 201           201 
 202           202 
 203           203 
 204           204 
 205           205 
 206           206 
 207           207 
 208           208 
 209           209 
 210           210 
 211           211 
 212           212 
 213           213 
 214           214 
 215           215 
 216           216 
 217           217 
 218           218 
 219           219 
 220           220 
 221           221 
 222           222 
 223           223 
 224           224 
 225           225 
 226           226 
 227           227 
 228           228 
 229           229 
 230           230 
 231           231 
 232           232 
 233           233 
 234           234 
 235           235 
 236           236 
 237           237 
 238           238 
 239           239 
 240           240 
 241           241 
 242           242 
 243           243 
 244           244 
 245           245 
 246           246 
 247           247 
 248           248 
 249           249 
 250           250 
 251           251 
 252           252 
 253           253 
 254           254 
 255           255
5
  • 1
    Welcome to Stack Overflow. Which application environment are you running this code in (e.g. Excel or other) Commented Sep 19, 2024 at 15:51
  • Thank you, @TylerH. It's Visual Basic 5.0 in 32-bit Windows. Commented Sep 19, 2024 at 19:17
  • FWIW I get the same output in VB6. You might add the [vb6] tag to the question to attract a wider audience. Haven't seen a VB5 question in ages! :) Commented Sep 20, 2024 at 11:23
  • Thank you for confirming, @StayOnTarget. I was wondering whether that was the case. As it happens, I'm pretty certain I have the answer and will post it soon as I can. Won't object if someone beats me to it, though. Commented Sep 20, 2024 at 12:51
  • Instead of InputB, which I never heard before, perhaps have a look at VB's Put / Get statements to read binary data. Commented Sep 23, 2024 at 9:41

2 Answers 2

0

The short answer is that 128 is one of the few single-byte character codes that Windows doesn't support, at least according to Visual Basic 5.0's help system. Although ChrB(128) & ChrB(0) is a valid expression, the character it yields is unrecognisable. In its place, Windows (or VB) puts a "?", which Asc correctly decodes as 63.

So why then doesn't Asc(Chr(128)) also return 63?

Chr(128) returns "€" (although it may appear as a non-printing character). Crucially, its two-byte encoding is not 128 and 0. Rather, it has a genuine two-byte encoding of 172 and 32. Asc, being the direct complement of Chr, accepts the two-byte character and returns 128.

The following table may help.

Expression (expr) Byte #1 Byte #2 Character Asc(expr)
ChrB(128) & ChrB(0) 128 0 "?" (unrecognised) 63
Chr(128) 172 32 "€" (euro sign) 128

According to VB5, most of the ANSI character codes in the range 128 to 159 are unsupported. If an attempt is made to generate a two-byte character manually from those codes using two ChrB calls, a "?" is returned.

How did I come by this answer? By flipping the question on its head: I wrote a short program to generate all 256 characters returned by Chr and, for each, used MidB to inspect the first and second bytes separately. The code and its output are below.

Exactly why this is the way it is, I don't know. Perhaps someone out there can say.

Some single-byte character sets reserve codes 128 to 159 for control rather than printable characters. It's possible that mapping those single-byte codes to alternative two-byte character representations was a way of "freeing up" those codes for additional characters (i.e. extending the character set) while respecting their reserved status.

Dim c As Integer
Dim b1 As Integer
Dim b2 As Integer
Dim s as String 
Dim i As Integer

Debug.Print "Code", "Byte #1", "Byte #2", "Character" 
For i = 0 To 255
    c = Asc(Chr(i))
    b1 = AscB(MidB(Chr(i), 1, 1))
    b2 = AscB(MidB(Chr(i), 2, 1))
    If Chr(i) <> ChrB(i) & ChrB(0) Then
        s = Chr(i)
    Else
        s = ""
    End If
    Debug.Print c, b1, b2, s
Next i
Code          Byte #1       Byte #2       Character
 0             0             0            
 1             1             0            
 2             2             0            
 3             3             0            
 4             4             0            
 5             5             0            
 6             6             0            
 7             7             0            
 8             8             0            
 9             9             0            
 10            10            0            
 11            11            0            
 12            12            0            
 13            13            0            
 14            14            0            
 15            15            0            
 16            16            0            
 17            17            0            
 18            18            0            
 19            19            0            
 20            20            0            
 21            21            0            
 22            22            0            
 23            23            0            
 24            24            0            
 25            25            0            
 26            26            0            
 27            27            0            
 28            28            0            
 29            29            0            
 30            30            0            
 31            31            0            
 32            32            0            
 33            33            0            
 34            34            0            
 35            35            0            
 36            36            0            
 37            37            0            
 38            38            0            
 39            39            0            
 40            40            0            
 41            41            0            
 42            42            0            
 43            43            0            
 44            44            0            
 45            45            0            
 46            46            0            
 47            47            0            
 48            48            0            
 49            49            0            
 50            50            0            
 51            51            0            
 52            52            0            
 53            53            0            
 54            54            0            
 55            55            0            
 56            56            0            
 57            57            0            
 58            58            0            
 59            59            0            
 60            60            0            
 61            61            0            
 62            62            0            
 63            63            0            
 64            64            0            
 65            65            0            
 66            66            0            
 67            67            0            
 68            68            0            
 69            69            0            
 70            70            0            
 71            71            0            
 72            72            0            
 73            73            0            
 74            74            0            
 75            75            0            
 76            76            0            
 77            77            0            
 78            78            0            
 79            79            0            
 80            80            0            
 81            81            0            
 82            82            0            
 83            83            0            
 84            84            0            
 85            85            0            
 86            86            0            
 87            87            0            
 88            88            0            
 89            89            0            
 90            90            0            
 91            91            0            
 92            92            0            
 93            93            0            
 94            94            0            
 95            95            0            
 96            96            0            
 97            97            0            
 98            98            0            
 99            99            0            
 100           100           0            
 101           101           0            
 102           102           0            
 103           103           0            
 104           104           0            
 105           105           0            
 106           106           0            
 107           107           0            
 108           108           0            
 109           109           0            
 110           110           0            
 111           111           0            
 112           112           0            
 113           113           0            
 114           114           0            
 115           115           0            
 116           116           0            
 117           117           0            
 118           118           0            
 119           119           0            
 120           120           0            
 121           121           0            
 122           122           0            
 123           123           0            
 124           124           0            
 125           125           0            
 126           126           0            
 127           127           0            
 128           172           32           €
 129           129           0            
 130           26            32           ‚
 131           146           1            ƒ
 132           30            32           „
 133           38            32           …
 134           32            32           †
 135           33            32           ‡
 136           198           2            ˆ
 137           48            32           ‰
 138           96            1            Š
 139           57            32           ‹
 140           82            1            Œ
 141           141           0            
 142           125           1            Ž
 143           143           0            
 144           144           0            
 145           24            32           ‘
 146           25            32           ’
 147           28            32           “
 148           29            32           ”
 149           34            32           •
 150           19            32           –
 151           20            32           —
 152           220           2            ˜
 153           34            33           ™
 154           97            1            š
 155           58            32           ›
 156           83            1            œ
 157           157           0            
 158           126           1            ž
 159           120           1            Ÿ
 160           160           0            
 161           161           0            
 162           162           0            
 163           163           0            
 164           164           0            
 165           165           0            
 166           166           0            
 167           167           0            
 168           168           0            
 169           169           0            
 170           170           0            
 171           171           0            
 172           172           0            
 173           173           0            
 174           174           0            
 175           175           0            
 176           176           0            
 177           177           0            
 178           178           0            
 179           179           0            
 180           180           0            
 181           181           0            
 182           182           0            
 183           183           0            
 184           184           0            
 185           185           0            
 186           186           0            
 187           187           0            
 188           188           0            
 189           189           0            
 190           190           0            
 191           191           0            
 192           192           0            
 193           193           0            
 194           194           0            
 195           195           0            
 196           196           0            
 197           197           0            
 198           198           0            
 199           199           0            
 200           200           0            
 201           201           0            
 202           202           0            
 203           203           0            
 204           204           0            
 205           205           0            
 206           206           0            
 207           207           0            
 208           208           0            
 209           209           0            
 210           210           0            
 211           211           0            
 212           212           0            
 213           213           0            
 214           214           0            
 215           215           0            
 216           216           0            
 217           217           0            
 218           218           0            
 219           219           0            
 220           220           0            
 221           221           0            
 222           222           0            
 223           223           0            
 224           224           0            
 225           225           0            
 226           226           0            
 227           227           0            
 228           228           0            
 229           229           0            
 230           230           0            
 231           231           0            
 232           232           0            
 233           233           0            
 234           234           0            
 235           235           0            
 236           236           0            
 237           237           0            
 238           238           0            
 239           239           0            
 240           240           0            
 241           241           0            
 242           242           0            
 243           243           0            
 244           244           0            
 245           245           0            
 246           246           0            
 247           247           0            
 248           248           0            
 249           249           0            
 250           250           0            
 251           251           0            
 252           252           0            
 253           253           0            
 254           254           0            
 255           255           0            
Sign up to request clarification or add additional context in comments.

Comments

0

Characters in the range 128-159 have different representations depending on your current codepage. Internally they are actually Unicode characters and that's why you are seeing two different bytes per character.

From your example you are probably using the Windows-1252 codepage which is common to America and Western Europe. Other countries use different codepages and you will see different characters in that range.

Taking the Euro sign as an example you could type it in Wordpad in two different ways:

  • Pressing Alt 0128 yields: (this works in the Windows-1252 codepage but will output a different character in other codepages).
  • Using its Unicode two-bytes representation (172 32) which amounts to

Hex(172+32*256) = 20AC in Hexadecimal

In Wordpad type 20AC and immediately press Alt X, that will produce in any codepage.

You can also verify it in Visual Basic, ChrW(&H20AC) will output universally, while Chr(128) will output only in the Windows-1252 codepage.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.