最近寫的
能在C生成和java.util.random一樣結果的偽隨機產生器
============================================
介紹:
構造函數
JavaRandom JavaRandom_new(int64_t seed)
這會使用單個int64_t種子一個新的隨機數發生器
解構函數
void JavaRandom_free(JavaRandom self)
方法
void JavaRandom_setSeed(JavaRandom self, int64_t seed)
此方法設置此隨機數生成器的使用單個int64_t種子的種子
void JavaRandom_nextBytes(JavaRandom self, int8_t* bytes, size_t bytes_length)
此方法生成隨機字節並將其置於用戶提供的字節數組
int32_t JavaRandom_nextInt(JavaRandom self, int32_t n)
n不得為負
如果n為0
此方法返回下一個偽從這個隨機數生成器的序列中均勻分布的int32_t值
如果n大於0
此方法返回一個偽隨機,均勻分布在0(含)int32_t值和指定值(不包括),從此隨機數生成器的序列中取出的
int64_t JavaRandom_nextLong(JavaRandom self)
此方法返回下一個偽從這個隨機數生成器的序列中均勻分布的int64_t值
bool JavaRandom_nextBoolean(JavaRandom self)
此方法返回下一個偽從這個隨機數生成器的序列中均勻分布的bool值
float JavaRandom_nextFloat(JavaRandom self)
此方法返回下一個偽從這個隨機數生成器的序列中均勻分布的0.0和1.0之間的float值
double JavaRandom_nextDouble(JavaRandom self)
此方法返回下一個偽從這個隨機數生成器的序列中均勻分布的0.0和1.0之間的double值
double JavaRandom_nextGaussian(JavaRandom self)
此方法返回下一個偽高斯(“正常地”)分布的均值為0.0,標準差為1.0從此隨機數生成器的序列的double值
============================================
使用範例:
#include <stdio.h>
#include "JavaRandom.h"
int main() {
JavaRandom random = JavaRandom_new(51);
for(int i = 0; i < 10; i++) {
printf("%d ", JavaRandom_nextInt(random, 100));
}
JavaRandom_free(random);
return 0;
}
輸出:
43 76 12 78 90 12 79 55 28 1
============================================
原理:
這個生成偽隨機數的方法稱為線性同餘方法
(linear congruential generator)
首先這個偽隨機生成器會有3個常數
a,b,m
還有一個亂數種子seed
seed = (a * seed + b) mod m
seed將會是你生成的偽隨機數
在生成下一個數時
seed將會再次被帶回上面的公式然後再生成下一個亂數
在java.util.random裡
a = 25214903917
b = 11
m = 2^48
但你很快就會發現
這個方法有個問題
生成出來的數一定會是一個奇數然後一個偶數
(
偶 + 奇 = 奇
奇 + 奇 = 偶
)
且越小的位數重複的越頻繁
為了解決這個問題
Java只取前32bits作為輸出
而非全48bits
如果要輸出64bits的資料(如Java的long)
則會呼叫兩次next()得到兩個32bits
然後合併成64bits
還有Java會對輸入的種子做一些調整
避免種子輸入為0時
a*seed變為0導致輸出的結果變得很小
剛輸入的seed會先XOR 25214903917 然後 AND (2^48 -1)
(
seed = (seed ^ 25214903917L) & ((1L << 48) -1);
)
============================================
寫這個程式的目的其實是要讓我可以用C寫一些和Minecraft有關的程式
因為很多Minecraft裡的隨機都是用java.util.random
要計算一些像是種子碼或遺跡生成之類的都會用到
例如我在GitHub裡面的example就是放minecraft Java版 1.7到1.15 地獄要塞生成公式
但是我不想學Java
所以打算甚麼都用C弄