33 lines
1.1 KiB
Text
33 lines
1.1 KiB
Text
require "bignum"
|
|
|
|
local const1 <const> = bigint.frombase("9e3779b97f4a7c15", 16)
|
|
local const2 <const> = bigint.frombase("bf58476d1ce4e5b9", 16)
|
|
local const3 <const> = bigint.frombase("94d049bb133111eb", 16)
|
|
local mask64 <const> = bigint.shl(bigint.one, 64) - bigint.one
|
|
|
|
mpz.init()
|
|
class splitmix64
|
|
function __construct(private state) end
|
|
|
|
function nextInt()
|
|
self.state = mpz.band(self.state + const1, mask64)
|
|
local z = self.state
|
|
z = mpz.band((mpz.bxor(z, mpz.shr(z, 30)) * const2), mask64)
|
|
z = mpz.band((mpz.bxor(z, mpz.shr(z, 27)) * const3), mask64)
|
|
return mpz.band(mpz.bxor(z, mpz.shr(z, 31)), mask64)
|
|
end
|
|
|
|
function nextFloat() return bigint.tonum(self:nextInt()) / (2.0 ^ 64) end
|
|
end
|
|
|
|
local randomGen = new splitmix64(bigint.new(1234567))
|
|
for _ = 1, 5 do print(randomGen:nextInt()) end
|
|
|
|
local counts = {0, 0, 0, 0, 0}
|
|
randomGen = new splitmix64(bigint.new(987654321))
|
|
for _ = 1, 100_000 do
|
|
local i = math.floor(randomGen:nextFloat() * 5)
|
|
counts[i + 1] += 1
|
|
end
|
|
print("\nThe counts for 100,000 repetitions are:")
|
|
for i = 1, 5 do print($" {i - 1} : {counts[i]}") end
|