将分数视为FALSE的逻辑运算符。

问题描述 投票:0回答:1

当我在小于1的数字上使用逻辑运算符时,得到了一个意想不到的结果。我以为VBA会将零以外的任何数字都视为TRUE,但它似乎将分数视为FALSE。太奇怪了。

我到底误解了什么。

我把它归结为这两行VBA代码。第一行返回了我所期望的结果,但是第二行没有。

谢谢kbrown4600

MsgBox 1 And True   ' returns 1
MsgBox 0.5 And True ' returns 0. Unexpected result
excel vba logical-operators coercion
1个回答
3
投票

位智运算符不做浮点数学运算,所以在给操作数之前,有一个隐式转换在进行。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

这要看具体情况。-1TrueTrueNot 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.

© www.soinside.com 2019 - 2024. All rights reserved.