vba 长数据类型溢出

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/297277/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 10:04:14  来源:igfitidea点击:

Long Datatype Overflow

excelvbastack-overflowlong-integer

提问by Henrik K

I am trying to do some prime factorisation with my VBA excel and I am hitting the limit of the longdata type -

我正在尝试用我的 VBA excel 做一些质因数分解,但我达到了long数据类型的限制-

Runtime Error 6 Overflow

运行时错误 6 溢出

Is there any way to get around this and still stay within VBA? I am aware that the obvious one would be to use another more appropriate programming language.

有什么办法可以解决这个问题并且仍然留在 VBA 中?我知道显而易见的是使用另一种更合适的编程语言。



Lance's solutionworks in so far that I am able to get the big numbers into the variables now. However, when I try to apply the MODfunction - bignumber MOD 2, for example - it still fails with error message

到目前为止,Lance 的解决方案有效,我现在能够将大数字放入变量中。但是,当我尝试应用该MOD函数时 -MOD 2例如bignumber - 它仍然失败并显示错误消息

Runtime Error 6 Overflow

运行时错误 6 溢出

采纳答案by Lance Roberts

MOD is trying to convert your DECIMAL type to LONG before operating on it. You may need to write your own MOD function for the DECIMAL type. You might try this:

MOD 正在尝试将您的 DECIMAL 类型转换为 LONG,然后再对其进行操作。您可能需要为 DECIMAL 类型编写自己的 MOD 函数。你可以试试这个:

r = A - Int(A / B) * B

where A & B are DECIMAL subtype of VARIANT variables, and r might have to be that large also (depending on your needs), though I only tested on a long.

其中 A & B 是 VARIANT 变量的 DECIMAL 子类型,而 r 也可能必须那么大(取决于您的需要),尽管我只测试了很长时间。

回答by Arvo

You can use Decimal data type. Quick hint from google: http://www.ozgrid.com/VBA/convert-to-decimal.htm

您可以使用十进制数据类型。来自谷歌的快速提示:http: //www.ozgrid.com/VBA/convert-to-decimal.htm

回答by bugmagnet

This is my Decimals.cls (VB6):

这是我的 Decimals.cls (VB6):

VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior  = 0  'vbNone
  MTSTransactionMode  = 0  'NotAnMTSObject
END
Attribute VB_Name = "Decimals"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True
Attribute VB_Ext_KEY = "SavedWithClassBuilder6" ,"Yes"
Attribute VB_Ext_KEY = "Top_Level" ,"Yes"
Option Explicit

'local variable(s) to hold property value(s)
Private mvarDec As Variant 'local copy

Public Property Let Dec(ByVal vData As Variant)
'used when assigning a value to the property, on the left side of an assignment.
'Syntax: X.Dec = 5
    mvarDec = CDec(vData)
End Property

Public Property Get Dec() As Variant
Attribute Dec.VB_UserMemId = 0
'used when retrieving value of a property, on the right side of an assignment.
'Syntax: Debug.Print X.Dec
    Dec = CDec(mvarDec)
End Property

and this is a testing program. The class has been setup so that you don't have to qualify with .Dec() on get and let.

这是一个测试程序。该类已设置好,因此您不必在 get 和 let 时使用 .Dec() 进行限定。

Dim dec1 As New Std.Decimals
Dim dec2 As New Std.Decimals
Dim dec3 As New Std.Decimals
Dim modulus As New Std.Decimals

Sub main()
    dec1 = "1000.000000001"
    dec2 = "1000.00000000000001"
    dec3 = dec1 + dec2
    Debug.Print dec1
    Debug.Print dec2
    Debug.Print dec3
    Debug.Print dec3 * dec3
    Debug.Print dec3 / 10
    Debug.Print dec3 / 100
    Debug.Print Sqr(dec3)
    modulus = dec1 - Int(dec1 / dec2) * dec2
    Debug.Print modulus
End Sub

and sample run

和样品运行

 1000.000000001 
 1000.00000000000001 
 2000.00000000100001 
 4000000.000004000040000001 
 200.000000000100001 
 20.0000000000100001 
 44.721359550007 
 0.00000000099999 
 1000.000000001 
 1000.00000000000001 
 2000.00000000100001 
 4000000.000004000040000001 
 200.000000000100001 
 20.0000000000100001 
 44.721359550007 
 0.00000000099999 

回答by dbb

Here is my "big multiply" routine for multiplying arbitrarily large numbers (eg 100 characters long). It works by splitting the input numbers, which are strings, into chunks of 7 digits (because then it can cross multiply them and store the results in Doubles).

这是我的“大乘”例程,用于乘以任意大的数字(例如 100 个字符长)。它的工作原理是将输入数字(字符串)拆分为 7 位数字的块(因为它可以将它们交叉相乘并将结果存储在双精度中)。

eg bigmultiply("1934567803945969696433","4483838382211678") = 8674289372323895422678848864807544574

例如 bigmultiply("1934567803945969696433","4483838382211678") = 8674289372323895422678848864807544574

Function BigMultiply(ByVal s1 As String, ByVal s2 As String) As String

Dim x As Long
x = 7

Dim n1 As Long, n2 As Long, n As Long
n1 = Int(Len(s1) / x + 0.999999)
n2 = Int(Len(s2) / x + 0.999999)
n = n1 + n2

Dim i As Long, j As Long
ReDim za1(n1) As Double
i = Len(s1) Mod x
If i = 0 Then i = x
za1(1) = Left(s1, i)
i = i + 1
For j = 2 To n1
 za1(j) = Mid(s1, i, x)
 i = i + x
Next j

ReDim za2(n2) As Double
i = Len(s2) Mod x
If i = 0 Then i = x
za2(1) = Left(s2, i)
i = i + 1
For j = 2 To n2
 za2(j) = Mid(s2, i, x)
 i = i + x
Next j

ReDim z(n) As Double
Dim u1 As Long, u2 As Long
Dim e As String
e = String(x, "0")

For u1 = 1 To n1
 i = u1
 For u2 = 1 To n2
   i = i + 1
   z(i) = z(i) + za1(u1) * za2(u2)
 Next u2
Next u1

Dim s As String, y As Double, w As Double, m As Long
m = n * x
s = String(m, "0")
y = 10 ^ x
For i = n To 1 Step -1
 w = Int(z(i) / y)
 Mid(s, i * x - x + 1, x) = Format(z(i) - w * y, e)
 z(i - 1) = z(i - 1) + w
Next i
'truncate leading zeros
For i = 1 To m
 If Mid$(s, i, 1) <> "0" Then Exit For
Next i
If i > m Then
 BigMultiply = ""
Else
 BigMultiply = Mid$(s, i)
End If

End Function