当我在小于1的数字上使用逻辑运算符时,得到了一个意想不到的结果。我以为VBA会将零以外的任何数字都视为TRUE,但它似乎将分数视为FALSE。太奇怪了。
我到底误解了什么。
我把它归结为这两行VBA代码。第一行返回了我所期望的结果,但是第二行没有。
谢谢kbrown4600
MsgBox 1 And True ' returns 1
MsgBox 0.5 And True ' returns 0. Unexpected result
位智运算符不做浮点数学运算,所以在给操作数之前,有一个隐式转换在进行。And
操作符来做它的位智。
"逻辑 "运算符是个骗局。根本就没有这种东西,我们一直被骗着--这又是一个圣诞老人牙仙子
复活节兔子(不要紧,有人告诉我复活节兔子是真的):它们是位智运算符,永远都是,不管你给它们什么。
由于位智运算的结果是 0
那么这只能说明隐式转换只是简单地切掉了小数部分。
一句话,......不要用非整数做位式的东西,一般来说要避免隐式类型转换。标准库里有一堆显式转换函数来解决这个问题。
Debug.Print VBA.Conversion.CLng(0.5) And True '<~ explicit conversion
CLng
is 有据可查 绕过 0.5
以至于 0
如果你需要确定是向下舍入到 0 还是向上舍入到 1,那么要明确。
Debug.Print CInt(0.5 + 0.01) And True '<~ explicit "round 0.5 up to 1"
在任何情况下,用非整数操作数对位运算符进行运算是没有意义的。
当小数部分正好是 0.5 时,CInt 和 CLng 总是将其舍入到最接近的偶数。例如,0.5取整为0,1.5取整为2。
围绕这些部分,Javascript有比这更糟糕的怪癖,不知道把隐式类型转换称为 "怪癖 "有多公平。
我以为VBA会把0以外的任何数字都视为TRUE
这要看具体情况。-1
是 True
但 True
是 Not False
. 这使得 True
-1
内部,可能是一个32位的整数,所以在二进制中它可能是这样的。
11111111 11111111 11111111 11111111
从位上看,布尔值 True
必须有这个表示法,因为这需要是对 False
:
00000000 00000000 00000000 00000000
位智逻辑需要两个操作数是相同的类型,这样位在两边的意义是一样的,否则位智操作--应该是 简单快捷 - 需要开始做复杂的分析来找出它在看什么,而它根本不需要......如果我们接受位智逻辑适用于整数类型,就这样。
你可以做 MsgBox 42 And 12
,你将得到位式结果 8
:
00000000 00000000 00000000 00101010 ' 42
00000000 00000000 00000000 00001100 ' 12
00000000 00000000 00000000 00001000 ' 8 (AND)
结果: And
运算符始终是一个位智和结果--我们所说的 "逻辑运算符 "只是对布尔操作数进行位智运算。
00000000 00000000 00000000 00000000 ' False
11111111 11111111 11111111 11111111 ' True
00000000 00000000 00000000 00000000 ' False (AND)
但是如果操作数本身不是整数类型的,那么它们就会被转换为一个整数类型 之前 操作者可以看到他们。这时 True
成为 -1
而这时 0.5
成为 0
.