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 似乎在两个桶中。您必须提醒自己,该值将被放入最先列出的桶中。这就是为什么在我的示例中桶以相反顺序列出的原因。这也是在休息日误读代码的绝佳机会。出于这个原因,在这种情况下我实际上并不推荐它,但如果您使用的是离散值,我认为这是可行的方法。它可以避免导致原始问题的错误。
我有以下功能:
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 似乎在两个桶中。您必须提醒自己,该值将被放入最先列出的桶中。这就是为什么在我的示例中桶以相反顺序列出的原因。这也是在休息日误读代码的绝佳机会。出于这个原因,在这种情况下我实际上并不推荐它,但如果您使用的是离散值,我认为这是可行的方法。它可以避免导致原始问题的错误。