AndAlso as between 语句造成错误分类

AndAlso as between statement makes wrong categorization

我有以下功能:

Public Function GetCategorized(ByVal val As Double) As UInt16
    Dim reVal As UInt16
    If val < 1.0625 Then
        reVal = 0
    ElseIf (1.0625 >= val) AndAlso (val < 1.1) Then
        reVal = 1
    ElseIf (1.1 >= val) AndAlso (val < 1.15) Then
        reVal = 2
    ElseIf (1.15 >= val) AndAlso (val < 1.2) Then
        reVal = 3
    ElseIf (1.2 >= val) AndAlso (val < 1.25) Then
        reVal = 4
    ElseIf (1.25 <= val) Then
        reVal = 5
    End If
    Return reVal
End Function

如果我将值 1.10716 放入函数中,我希望得到值 2,因为该值介于 1.1 和 1.15 之间,但我得到的是值 3,谁能解释一下,那是什么以及在哪里我弄错了,因为我没看到。

1.1 >= 1.10716吗?

否(比 1.1 大 0.0716)。

由于您使用的是短路逻辑运算符,因此它不会评估 val < 1.15 条件并移至下一个 ElseIf。 (即使你没有使用短路版本,整个条件仍然是错误的。)

在接下来的ElseIf中,1.15 >= 1.10716为真,另外1.10716 < 1.2也为真,所以整个条件为真,返回3

正如我在评论中所说,您的代码的主要问题是您在每个 ElseIf 的第一次测试中都有 val 和 number switch round。在任何情况下,您都可以像这样简化函数:

Public Function GetCategorized(ByVal val As Double) As UInt16
    If val < 1.0625 Then Return 0
    If Val < 1.1 Then Return 1
    If Val < 1.15 Then Return 2
    If Val < 1.2 Then Return 3
    If Val < 1.25 Then Return 4
    Return 5
End Function

与其他答案略有不同。我还建议您设置有意义的变量名称。学习调试和单步执行代码,您会注意到这一切发生得非常快。

Public Function GetCategorized(ByVal val As Double) As UInt16

    Dim category As UInt16

    If val < 1.0625 Then
        category = 0
    ElseIf val < 1.1 Then
        category = 1
    ElseIf val < 1.15 Then
        category = 2
    ElseIf val < 1.2 Then
        category = 3
    ElseIf val < 1.25 Then
        category = 4
    Else
        category = 5
    End If

    Return category
End Function

像这样尝试将值放入桶中时,我有点喜欢 Select Case。它有一个明显的 "pick one of the following" 语法,并且它支持极其可读的 v1 TO v2 范围语法。

  Public Function GetCategorized(ByVal val As Double) As UInt16
     Dim reVal As UInt16

     Select Case val
        Case Is >= 1.25
           reVal = 5
        Case 1.2 To 1.25
           reVal = 4
        Case 1.15 To 1.2
           reVal = 3
        Case 1.1 To 1.15
           reVal = 2
        Case 1.05 To 1.1
           reVal = 1
        Case Else
           reVal = 0
     End Select

     Return reVal
  End Function

浮点值不如整数等离散类型那么好,因为用范围语法声明的桶必须在它们的端点重叠(如果一个桶的上限是值 X,另一个桶需要有 X 作为下限,否则你最终会在桶之间有间隙)。这意味着 X 似乎在两个桶中。您必须提醒自己,该值将被放入最先列出的桶中。这就是为什么在我的示例中桶以相反顺序列出的原因。这也是在休息日误读代码的绝佳机会。出于这个原因,在这种情况下我实际上并不推荐它,但如果您使用的是离散值,我认为这是可行的方法。它可以避免导致原始问题的错误。