Overflow del tipo di dati lungo
-
08-07-2019 - |
Domanda
Sto cercando di fare un po 'di scomposizione in fattori primi con il mio VBA Excel e sto raggiungendo il limite del tipo di dati long
-
Errore di runtime 6 Overflow
C'è un modo per aggirare questo problema e rimanere ancora all'interno di VBA? Sono consapevole che l'ovvio sarebbe usare un altro linguaggio di programmazione più appropriato.
La soluzione di Lance funziona così tanto che sono ora in grado di inserire i grandi numeri nelle variabili. Tuttavia, quando provo ad applicare la funzione MOD
, ad esempio bignumber MOD 2
, continua a non riuscire con il messaggio di errore
Errore di runtime 6 Overflow
Soluzione
MOD sta cercando di convertire il tuo tipo DECIMAL in LONG prima di operare su di esso. Potrebbe essere necessario scrivere la propria funzione MOD per il tipo DECIMAL. Potresti provare questo:
r = A - Int(A / B) * B
dove A & amp; B è un sottotipo DECIMALE di variabili VARIANT e potrebbe essere necessario che r sia così grande (a seconda delle esigenze), anche se ho testato solo a lungo.
Altri suggerimenti
È possibile utilizzare il tipo di dati decimali. Suggerimenti rapidi da google: http://www.ozgrid.com/VBA/convert -to-decimal.htm
Questo è il mio 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
e questo è un programma di test. La classe è stata impostata in modo da non doverti qualificare con .Dec () su get and let.
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
ed esempio di esecuzione
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
Ecco la mia "grande moltiplicazione" routine per la moltiplicazione di numeri arbitrariamente grandi (ad es. lunghi 100 caratteri). Funziona suddividendo i numeri di input, che sono stringhe, in blocchi di 7 cifre (perché quindi può incrociarli moltiplicandoli e archiviare i risultati in Double).
es. 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