2016-10-12 3 views
4

Ich habe in Excel VBA einen Überlauffehler festgestellt und finde mich nicht zurecht. Während die Microsoft-Dokumentation angibt, dass der Bereich für Doppelpunkte ~ 1,8E308 erreichen sollte, erhalte ich einen Überlauffehler für Zahlen, die deutlich unter diesem Schwellenwert liegen. Mein Code ist wie folgt:Überlauffehler in Excel VBA mit Typ Double

Public Function Fixed_Sample_Nums(ByVal n As Long, seed As Long) As Double() 

    Dim x() As Double, y() As Double, i As Long 
    ReDim y(1 To n) 
    ReDim x(1 To n) 

    x(1) = (CDbl(48271) * seed) Mod CDbl(2^31 - 1) 

    For i = 2 To n 
     x(i) = (CDbl(48271) * CDbl(x(i - 1))) Mod (CDbl(2^31 - 1)) 
     y(i) = CDbl(x(i))/CDbl(2^31 - 1) 
    Next i 

    Fixed_Sample_Nums = y 

End Function 

'I receive the error in the first iteration of the for loop with 
'seed equal to any value >= 1 (i.e. w/ seed = 1): 

Debug.Print((CDbl(48271) * CDbl(48271)) Mod (CDbl(2^31 - 1))) 

'results in an overflow error 

Ich bin versucht einen Pseudo-Zufallszahlengenerator zu erzeugen, die in jedem ‚seed‘ Wert bis zu und einschließlich 2^31 erfolgen kann - 1. Die for-Schleife sollte in der Lage sein Iterieren mindestens 9.999 mal (dh n = 10000). Wenn der Überlauffehler nicht innerhalb der ersten paar Iterationen auftritt, wird er höchstwahrscheinlich für keine nachfolgende Iteration auftreten.

Wie Sie sehen können, konvertiere ich jede Integer vor jeder Berechnung in ein Double. Ich bin mir der Tatsache bewusst, dass Arrays die Bytegröße der Berechnung wesentlich erhöhen, aber das scheint nicht das aktuelle Problem zu sein, da ich die obige Beispielrechnung direkt in das unmittelbare Fenster kopiert habe und immer noch den Überlauffehler erhalten habe. Meine Versuche, online eine Lösung zu finden, haben nichts gebracht, daher würde ich jede Eingabe sehr schätzen. Danke im Voraus!

+0

42. Mod 2^31 auch abgestürzt, im Gegensatz zu 42 Mod (2.^31 -1) ... vielleicht ein undokumentierter (google gab nichts) Schwäche des Mods. Wer benutzt das überhaupt? O.O – Pierre

+0

http://www.cpearson.com/excel/ModFunction.aspx –

+0

@DavidZemens Danke für den Link! Lustige Sache ist, ich habe bereits versucht, meine eigene Funktion zu erstellen, führt immer noch zu einem Überlauffehler. Der Pseudozufallszahlengenerator arbeitet auch in Arbeitsblattform ohne Überlauf, aber ich muss dafür eine VBA-Funktion erstellen. –

Antwort

3

Versuchen Sie es mit Chip Pearson XMod Funktion:

x(i) = XMod((CDbl(48271) * seed), CDbl(2^31 - 1)) 

Wie stellt er fest:

Sie können auch Überlauffehler in VBA mit dem Mod-Operator mit sehr großen Zahlen bekommen. Zum Beispiel

Dim Number As Double 
Dim Divisor As Double 
Dim Result As Double 

Number = 2^31 
Divisor = 7 
Result = Number Mod Divisor ' Overflow error here. 

-Code für die Funktion:

Function XMod(ByVal Number As Double, ByVal Divisor As Double) As Double 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 
' XMod 
' Performs the same function as Mod but will not overflow 
' with very large numbers. Both Mod and integer division (\) 
' will overflow with very large numbers. XMod will not. 
' Existing code like: 
'  Result = Number Mod Divisor 
' should be changed to: 
'  Result = XMod(Number, Divisor) 
' Input values that are not integers are truncated to integers. Negative 
' numbers are converted to postive numbers. 
' This can be used in VBA code and can be called directly from 
' a worksheet cell. 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 
    Number = Int(Abs(Number)) 
    Divisor = Int(Abs(Divisor)) 
    XMod = Number - (Int(Number/Divisor) * Divisor) 
End Function 

Weitere Details:

http://www.cpearson.com/excel/ModFunction.aspx

+0

Danke nochmal! Ich hatte versucht, dann mit einer ähnlichen Funktion zu erstellen und immer noch den Überlauffehler erhalten. Jetzt habe ich Pearson's kopiert und eingefügt .. Immer noch einen Überlauffehler. –

+1

Wow, nvm .. In meinem ersten Versuch, nachdem ich Pearsons Funktion erstellt hatte, konvertierte ich zu Longs und nicht zu Double x). Die PRNG-Funktion arbeitet nun syntaktisch und semantisch. Vielen Dank! –