我下面有一些代碼可以在 Excel 中生成一些亂數:
Sub Macro1()
Dim RA1 As Variant
ReDim RA1(1 To 5)
For i = 1 To 5
Rnd (-1)
Randomize i
For j = 1 To 5
RA1(j) = Rnd
Next j
With Sheets("Sheet1")
.Range(Cells(i, 1), Cells(i, 5)).Value = RA1
End With
Next i
End Sub
這段代碼基本上生成 5 行 5 個亂數,但它沒有完全按照預期運行。當我在 iMac (2021) 上運行此代碼時,每行中的亂數完全相同。然而,這段代碼應該生成的是 5 行不同的亂數。
這就是事情變得更加奇怪的地方。當我在我的 Windows 筆記本電腦上運行此代碼時,輸??出符合要求 - 也就是說,我確實得到了 5 行不同的亂數。我已經和我的教授談過這個問題,他也在他的 Windows 電腦上嘗試過,得到了 5 行不同的亂數。
我們得出的結論是,我的 iMac 的 Excel 中的某些設定阻止了此代碼正常運行。我的教授還懷疑這本質上不是 Apple 的問題,因為他說以前沒有人向他提出過這個問題。
總而言之,我們基本不知道為什么我的iMac無法運行這段代碼。有沒有人對為什么這里存在這種差異有任何猜測?例如,我的 iMac 的 Excel 中是否有任何設定阻止了我的代碼正常運行?
任何解釋和解決方案將不勝感激!:)
注意:我之前沒有更改 iMac 的 Excel 中的任何設定(好吧,至少我不知道),所以現在一切都應該是默認的。
uj5u.com熱心網友回復:
如果您閱讀Randomize 陳述句的手冊,您可以找到以下內容:
要重復亂數序列,請在使用帶有數字引數的 Randomize 之前立即使用負引數呼叫 Rnd。使用具有相同數字值的 Randomize 不會重復之前的序列。
所以我強烈建議洗掉Rnd (-1)它,使其重復亂數序列。
還嘗試從中洗掉種子Randomize i并使用,Randomize以便計算機將系統計時器作為種子(以獲得更好的亂數)。
// 根據評論編輯
如果您每次都需要相同的數字但所有行/列中的數字不同,那么您可能需要在第一個回圈之前進行初始化。
Rnd -1
Randomize 1 'if you don't need the same seed everytime use Randomize without number
For i = 1 To 5
uj5u.com熱心網友回復:
您描述的行為是一個錯誤。
首先,如果我們替換行:
Randomize i
和:
Randomize 0
我們可以看到,在 Windows 上,我們得到與在 Mac 上完全相同的重復值:

這立即向我暗示只能有兩種可能的解釋:
- 可能演算法不一樣
- 存在問題并且 的值
i未正確傳遞/讀取。
為了找到規則,我使用了一個單獨的方法(brute-forced i/x)并找到了以下幻數。同樣,如果我們替換行:
Randomize i
和:
#If Mac Then
Dim arr() As Variant: arr = Array(26489, 63707, 185603, 15365, 92513)
Randomize i / arr(i - 1)
#Else
Randomize i
#End If
我們在 Windows 和 Mac 上得到相同的結果。
我在這些幻數中找不到清晰的模式,所以我放棄了演算法不同的說法。這讓我找到了問題/錯誤。
經過一些試驗和錯誤,我發現如果我們將Double資料型別傳遞給該Randomize方法,它不會讀取完整的 8 個位元組,而是僅讀取前 4 個位元組。這就是除以這些幻數起作用的原因,因為結果數字(這些除法的)使用前 4 個位元組(包括指數位)而不是 8 個完整位元組。
解決方法是將雙精度值偏移(向左)4 個位元組。這是適用于 Windows 和 Mac 的最終代碼:
Option Explicit
#If Mac Then
#If VBA7 Then
Public Declare PtrSafe Function CopyMemory Lib "/usr/lib/libc.dylib" Alias "memmove" (Destination As Any, Source As Any, ByVal Length As LongPtr) As LongPtr
#Else
Public Declare Function CopyMemory Lib "/usr/lib/libc.dylib" Alias "memmove" (Destination As Any, Source As Any, ByVal Length As Long) As Long
#End If
#End If
Sub Macro1()
Dim i As Long
Dim j As Long
Dim RA1 As Variant
ReDim RA1(1 To 5)
For i = 1 To 5
Rnd (-1)
#If Mac Then
Dim d As Double
d = CDbl(i)
CopyMemory d, ByVal VarPtr(d) 4, 4 'Read the last 4 double bytes into the first 4
Randomize d
#Else
Randomize i
#End If
For j = 1 To 5
RA1(j) = Rnd
Next j
With Sheets("Sheet1")
.Range(Cells(i, 1), Cells(i, 5)).Value = RA1
End With
Next i
End Sub
您會注意到我還添加Option Explicit、宣告了所有變數并縮進了代碼。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/336059.html
