簡體   English   中英

如何在 c 中為線性同余生成器 LCG 實現模數 2^64

[英]how to implement the modulus 2^64 in c for linear congruential generator LCG

這是線性同余生成器的 C 語言實現,具有以下公式:

X_{n+1}=a*X_{n} \\bmod m

下面是線性同余生成器函數的兩個版本,第一個函數生成一個 64 位整數,第二個函數生成一個雙精度數。

下面代碼中的模數是 2^64−1。 我想將模數重寫為 2^64,當我嘗試由於數據類型而出現錯誤時。 由於 2^64 是一個 65 位,並且該函數具有一個“uint64_t”數據類型,它包含 64 位。 我尋找解決方案來解決這個問題,比如使用 128 位數據類型,但我在 Mac 上使用 Xcode 並且它不支持它,有些人建議使用 GPM,但我不喜歡它。 我想過將 Modulus 存儲在一個數組中,但我不知道以后如何才能使最終輸出成為 64 位整數。

有什么簡單的方法可以做到嗎? 因為我需要第一個函數的最終輸出是一個 64 位整數,而第二個函數的輸出是一個雙精度數,所以稍后我可以在進一步的計算中使用它們。

編輯:在代碼中,模數的值為 m=18446744073709551615,即 2^64−1。 我想將其更改為 m= 18446744073709551616,即 2^64。 由於數據類型,當我這樣做時出現錯誤。 如何將模數更改為 m= 18446744073709551616 = 2^64?

uint64_t linear_congruential()
   {
    uint64_t s= 1442695040888963407;// seed
    unsigned long long int m=18446744073709551615; // The Modulus 2ˆ64−1    
    uint64_t a=6364136223846793005; // the multiplier a
    s=(s * a )&m;
    return s;
    }

第二個具有雙精度的函數:

double linear_congruential_d()
 {
  double q;
  uint64_t s= 1442695040888963407; //seed
  unsigned long long int m=18446744073709551615; // The Modulus 2ˆ64−1
  uint64_t a=6364136223846793005 ; // the multiplier a
  s=(s * a )&m;
  q=s/m; 
  return q;
 }

這些函數中使用的模數不是$2^{64}-1$而是$2^{64}$
如果$x$是 2 的冪,您總是可以將模$x$除以:

s = s*a & (x-1);

這就是這里所做的。

無論如何,此操作在這里是多余的,因為通過切斷 128 位長結果的較高 64 位,乘法的結果會自動截斷為 64 位。 簡化版:

uint64_t linear_congruential()
{
    static uint64_t s= 1442695040888963407; // seed
    const uint64_t a = 6364136223846793005; // the multiplier a
    s *= a;
    return s;
}

第二個功能將不起作用。 由於 s 和 m 是整數,因此 s/m 將作為整數除法進行,即結果將向下舍入到下一個整數。 它將(幾乎)始終為 0。相反,您應該這樣寫:

q = s / (double)m;

編輯:變量 s 必須是靜態的。 它必須為下一次調用該函數保留其值。

順便說一句,將 64 位無符號整數轉換為雙精度數時,標准方法是:

unsigned long long my_big_number = .....;
double my_double_number = my_big_number / (double)MAX_UINT;

但這可能更快:

double my_double_number = ( static_cast<double>(my_big_number>>2) / 2.0);

這利用了 IEEE 雙精度位格式,如果您的整數是全范圍 64 位,那么雙精度數將在[ 0.0 .. 2.0 )范圍內。 最后除以 2.0 使其成為目標范圍[ 0.0 .. 1.0 )將比除以(double)MAX_INT更快。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM