【问题标题】:Confusing Logical Operators in VB.NETVB.NET 中令人困惑的逻辑运算符
【发布时间】:2017-09-20 19:44:18
【问题描述】:

我正在使用用 VB 编写的遗留代码库,遇到了一个我不理解的条件运算符,无法弄清楚要搜索什么来解决它。

我正在处理的是以下代码和结果为 true 的变量。我不明白的具体部分是(1)第一个X和第一个parens(-2之间的关系和(2)X < 2的作用

  • 如果X 是低于-2 的值,则计算结果为false。
  • 如果X 的值高于2,则计算结果为true。
  • 如果Y 低于5,则它按预期计算为true。

X = 3
Y = 10

If X > (-2 And X < 2) Or Y < 5 Then
    'True
Else
    'False
End If

【问题讨论】:

  • 不确定到底发生了什么(因此只是一个评论),但我敢打赌这里的技巧依赖于And 是一个 bitwise 运算符这一事实,而不是而不是直接的条件运算符。如果有任何借口,我会重新编写它以便更容易理解它是如何遵循规范的。现有代码可能比更容易理解的代码更快,但我怀疑这种表达方式是否会以一种有意义的方式提高应用程序的性能。
  • @JoelCoehoorn - 我也完全同意重写它,因为它对性能并不重要。不幸的是,我不知道代码库的这个特定部分中逻辑运算符的初衷,因此试图弄清楚它可能试图解决什么:/
  • 您将整数与布尔值进行比较。和一个整数的布尔值。这让编译器很头疼,需要对其进行整理。可能有点令人惊讶的结果是 True 等于 -1。这是一个相当出色的举措,可确保 And 和 Or 运算符既可以用作位运算符,也可以用作逻辑运算符。最好不要让编译器头疼,它也不会让你头疼。
  • 你能确定输出是确实想要的吗?我没有任何证据支持这一点,但我有一种感觉,只是感觉这段代码有错别字,原意是简单写If (X &gt; -2 And X &lt;2) Or Y &lt; 5,不涉及按位运算,因此可以通过替换来优化And & Or 与 AndAlso & OrElse。如果您能提供更多上下文,也许我们可以找到证据来证明或反驳这一点。

标签: vb.net conditional logical-operators


【解决方案1】:

我将把这篇文章的表达式中的Or Y &lt; 5 部分视为无趣,并将自己限制在表达式的X &gt; (-2 And X &lt; 2) 一侧。

在过去的几年里我没有做太多的 VB,所以我开始研究 VB 中的运算符优先规则,以确保我做对了。我找到了有关 VBA 和 VB.Net 的权威信息,以及一些可能是 VB6 但也可能是 2013 版 VB.Net 的 MSDN 资料。但是,无论您将And 视为逻辑还是位,它们都赋予&lt; 和&gt; 比较运算符高于And 运算符的优先级。

有了这些信息,并且还知道我们必须先查看括号内的内容,我现在确信要评估的表达式的第一部分是 X &lt; 2(而不是 -2 And X)。此外,我们知道这将产生一个布尔结果,然后必须将此布尔结果转换为整数以执行 按位(非逻辑)And 和 @987654332 @。这个结果(我称之为n)仍然是一个整数,最后可以比较一下X &gt; n,这将产生表达式的最终结果为布尔值。

我做了更多的挖掘工作,发现this Stack Overflow answer 关于将 VB 布尔值转换为整数。虽然不是最终的文档,但我有幸见到了作者(嗨@JaredPar)并且知道他在微软的 VB 编译器团队工作,所以他应该知道他在说什么。这表明VB布尔True具有惊人的-1整数值! False 变成更普通的0。

此时我们需要谈谈负数的二进制表示。以this reference 为指导(我依稀记得在大学里学过这个,但这不是我每天都需要的那种东西),我将提供一个从 -3 到 +3 的整数转换表只有 4 位的虚整数大小(简短版本:反转位模式并加一以获得负表示):

-3 1101 -2 1110 -1 1111 -- 这有助于解释**为什么** -1 用于 True 0 0000 1 0001 2 0010 3 0010

退后一步,现在让我们考虑原始的-2 And X &lt; 2 括号,并查看X &lt; 2 在逐位And 和-2 之后的真(-1)和假(0)可能结果: -2 (1110) 和真 (1111) = 1110 = -2 -2 (1110) 和假 (0000) = 0000 = 0

使用-1 位模式的真正意义在于anything And True 会产生与您开始时相同的东西,而任何And False 都会产生全零。

所以如果X &lt; 2 你得到True,结果是-2;否则你最终会得到0。有趣的是,如果我们的语言对True 使用正数,您最终会得到相同的0000 值,对And 和-2 进行逐位运算,您可以从False (1110 And 0001 )。

现在我们知道的足够多,可以查看X 的一些值并确定整个原始表达式的结果。任何正整数都大于-2 和0,因此表达式应生成True。 0 和 -1 是相似的:它们小于 2,因此只会在大于 -2 时再次进行比较,因此总是导致 True。不过,负二以及下面的任何内容都应该是False。

不幸的是,这意味着您可以将整个表达式简化为X &gt; -2。要么我对运算符优先级有误,我对负整数位模式的引用是错误的,要么您使用的 VB 版本将 True 转换为 -1 以外的其他值,或者此代码只是 方式从一开始就过于复杂。

【讨论】:

    【解决方案2】:

    我认为顺序如下:

    r = -2 and X '输出X,最低有效位设置为0(表示第一个较小的偶数)

    r = (r

    r = (X > r) '输出-1或0

    r = r 或 (Y

    使用 AndAlso 和 OrElse。

    【讨论】:

      猜你喜欢
      • 2019-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-19
      • 1970-01-01
      • 2022-11-22
      • 1970-01-01
      • 2023-04-02
      相关资源
      最近更新 更多