标题: AscW函数返回负数的问题
作者: Demon
链接: https://demon.tw/programming/ascw-negative.html
版权: 本博客的所有文章,都遵守“署名-非商业性使用-相同方式共享 2.5 中国大陆”协议条款。
其实这个问题在以前写《VBS实现PHP的urlencode函数》的时候就碰到了,但是当时没有记下来,造成写前面一篇文章《VBS实现Unicode转UTF-8》的时候重蹈覆辙。还是记录下来吧,免得以后又忘记。
MSDN文档对AscW的说明是:AscW是为使用Unicode字符的32位平台提供的。它返回Unicode(宽型)字符代码,因此可以避免从ANSI到Unicode的代码转换。
按照参考手册的定义,AscW函数应该返回一个字符的Unicode字符编码,但是直接拿返回的结果来用的话会有潜在的BUG,正如我碰到的。
“魔”字的Unicode编码是39764,测试如下代码
c = AscW("魔") If c > 127 Then WScript.Echo "Not ASCII" Else WScript.Echo "ASCII" End If
你认为返回的结果是什么?"Not ASCII"?错!返回的结果是"ASCII"。
这就是潜在的BUG,对某些中文(当然还有其他字符)AscW函数返回的值是负数!如果你的代码拿这个值与一个正数比较大小,逻辑值将是False!
为什么呢?因为AscW的返回值的子类型是Integer,而VBS中Integer的取值范围是从-32768到32767。39764 > 32767,造成了溢出,所以返回负数。
怎样才能得到正确的结果呢?答案把子类型是转化成Long,Long的取值范围是-2,147,483,648到2,147,483,647,不会造成溢出。
WScript.Echo CLng("&H" & Hex(AscW("魔")))
先用Hex函数把AscW的返回值转化成十六进制的字符串,加上VBS中十六进制前缀&H,最后用CLng函数把子类型转化成Long。这样就能得到39764这个正确的Unicode编码值了。
赞赏微信赞赏支付宝赞赏
随机文章:
[…] AscW函数返回负数的问题 (http://demon.tw/programming/ascw-negative.html) […]
[…] 如果字符的代码点(code point)大于32,767,那么AscW函数会返回负数(详见《AscW函数返回负数的问题》)。自定义函数MyAscW的本意是AscW的改进版,但是依然返回了负值。 […]
转成字符串速度大丈夫么【一天到晚用VB却思考着速度的人【是没救的
可以CLng(intCode) And 65535不是就可以了么~