有没有办法在Excel VBA中强制循环整数溢出?
我试图将一些Java代码转换为Excel,所需的hashcode函数会生成一个溢出错误,而不是换行为负数有没有办法在Excel VBA中强制循环整数溢出?,vba,Vba,我试图将一些Java代码转换为Excel,所需的hashcode函数会生成一个溢出错误,而不是换行为负数 Function FnGetStringHashCode(ByVal str As String) As Integer Dim result, i FnGetStringHashCode = 17 For i = 1 To Len(str) Dim c, a c = Mid(str, i, 1) a = AscW(c)
Function FnGetStringHashCode(ByVal str As String) As Integer
Dim result, i
FnGetStringHashCode = 17
For i = 1 To Len(str)
Dim c, a
c = Mid(str, i, 1)
a = AscW(c)
FnGetStringHashCode = 31 * FnGetStringHashCode + a
Next i
End Function
在Excel VBA中有这样做的方法吗?我对我们的脚本做了一些修改。主要区别在于返回函数的类型。现在它返回Variant。因为decimal是Variant的子集,它可以存储比long更大的数字,所以我认为这是一个好的解决方案()-我不知道是否可以显式返回decimal。这是剧本
Function FnGetStringHashCode(ByVal str As String) As Variant
Dim tmp As Variant, c As String, a As Integer, i As Integer
tmp = 17
For i = 1 To Len(str)
c = Mid$(str, i, 1)
a = AscW(c)
tmp = 31 * tmp + a
Next i
FnGetStringHashCode = tmp
End Function
还有一点测试程序
Sub test()
Debug.Print CStr(FnGetStringHashCode("dawdaedae"))
End Sub
虽然没有内置的方法来实现这一点,但计算很简单:
Public Function coerceLongToInt(toCoerce As Long) As Integer
Const MIN_INT As Long = -32768
Const MAX_INT As Long = 32767
Const NUM_INTS As Long = MAX_INT - MIN_INT + 1
Dim remainder As Long
remainder = toCoerce Mod NUM_INTS
If remainder > MAX_INT Then
coerceLongToInt = remainder - NUM_INTS
ElseIf remainder < MIN_INT Then
coerceLongToInt = remainder + NUM_INTS
Else
coerceLongToInt = remainder
End If
End Function
您可以这样使用它:
Function FnGetStringHashCode(ByVal str As String) As Integer
Dim result, i
FnGetStringHashCode = 17
For i = 1 To Len(str)
Dim c, a
c = Mid(str, i, 1)
a = AscW(c)
FnGetStringHashCode = coerceLongToInt(31 * CLng(FnGetStringHashCode) + a)
Next i
End Function
您需要在其中调用'CLng'以防止VBA在计算中间值(31*[some integer>=1058])时引发溢出错误。我找不到如何定义Decimal类型的变量,只是转换函数是CDec()。感谢您的响应@MPękalski,但实际上我仍然希望该值溢出。如果我想存储一个大于
long
的数字,这是正确的答案。对不起,我一定是赶时间,我没有读到您希望溢出时的值为负数。至于现在,我不知道怎么做,如果不在我的脚本中添加一个条件,如果它大于Long,那么返回一个负数等等…谢谢,我最终不得不在我的应用程序中将它从整数和Long改为Long和decimal(我问这个问题时没有意识到这是必要的),但在其他方面,我做到了
Function FnGetStringHashCode(ByVal str As String) As Integer
Dim result, i
FnGetStringHashCode = 17
For i = 1 To Len(str)
Dim c, a
c = Mid(str, i, 1)
a = AscW(c)
FnGetStringHashCode = coerceLongToInt(31 * CLng(FnGetStringHashCode) + a)
Next i
End Function