mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-11-26 00:53:00 +00:00
Failed implementation of xoshiro256++ becaause Lua doesn't have an integer type :-( :-( :-( :-( :-( :-( :-(
This commit is contained in:
parent
0b0595a1d3
commit
457f436a09
2 changed files with 120 additions and 0 deletions
111
worldeditadditions/utils/random.lua
Normal file
111
worldeditadditions/utils/random.lua
Normal file
|
@ -0,0 +1,111 @@
|
|||
--- Implementation of the xoshiro++ random number generation algorithm.
|
||||
-- Ported from C by Starbeamrainbowlabs
|
||||
-- @ref https://en.wikipedia.org/wiki/Xorshift#xoshiro_and_xoroshiro
|
||||
-- @class
|
||||
local Xoshiro = {}
|
||||
Xoshiro.__index = Xoshiro
|
||||
|
||||
--- Creates a new Xoshiro instance.
|
||||
-- @returns Xoshiro The new Xoshiro instance.
|
||||
function Xoshiro.new(seed)
|
||||
seed = seed or 4898416254654
|
||||
local result = {
|
||||
state = {
|
||||
34862381629 ^ seed,
|
||||
87782734023 ^ seed,
|
||||
59217486042 ^ seed,
|
||||
68724585416 ^ seed
|
||||
}
|
||||
}
|
||||
setmetatable(result, Xoshiro)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Polyfill for the bitshift left operator that's missing in Lua.
|
||||
-- @source https://ebens.me/post/simulate-bitwise-shift-operators-in-lua/
|
||||
-- @param value number The number to bitshift left.
|
||||
-- @param places number The number of bits to shift it by to the left.
|
||||
function Xoshiro._bitshift_left(value, places)
|
||||
return value * 2 ^ places
|
||||
end
|
||||
|
||||
--- Polyfill for the bitshift right operator that's missing in Lua.
|
||||
-- @source https://ebens.me/post/simulate-bitwise-shift-operators-in-lua/
|
||||
-- @param value number The number to bitshift right.
|
||||
-- @param places number The number of bits to shift it by to the right.
|
||||
function Xoshiro._bitshift_right(value, places)
|
||||
return math.floor(value / 2 ^ places)
|
||||
end
|
||||
|
||||
-- Bitwise OR polyfill.
|
||||
-- The source also has polyfills for bitwise AND, NOT, and XOR.
|
||||
-- @source https://stackoverflow.com/a/25594410/1460422
|
||||
-- @param a number The left-hand argument to the bitwise or operation.
|
||||
-- @param b number The right-hand argument to the bitwise or operation.
|
||||
-- @returns number The result of the bitwise or operation.
|
||||
function Xoshiro._bitwise_or(a,b)
|
||||
local p,c=1,0
|
||||
while a+b>0 do
|
||||
local ra,rb=a%2,b%2
|
||||
if ra+rb>0 then c=c+p end
|
||||
a,b,p=(a-ra)/2,(b-rb)/2,p*2
|
||||
end
|
||||
return c
|
||||
end
|
||||
|
||||
-- Bitwise XOR polyfill.
|
||||
-- The source also has polyfills for bitwise AND, OR, and NOT.
|
||||
-- @source https://stackoverflow.com/a/25594410/1460422
|
||||
-- @param a number The left-hand argument to the bitwise xor operation.
|
||||
-- @param b number The right-hand argument to the bitwise xor operation.
|
||||
-- @returns number The result of the bitwise xor operation.
|
||||
function Xoshiro._bitwise_xor(a,b)
|
||||
local p,c=1,0
|
||||
while a>0 and b>0 do
|
||||
local ra,rb=a%2,b%2
|
||||
if ra~=rb then c=c+p end
|
||||
a,b,p=(a-ra)/2,(b-rb)/2,p*2
|
||||
end
|
||||
if a<b then a=b end
|
||||
while a>0 do
|
||||
local ra=a%2
|
||||
if ra>0 then c=c+p end
|
||||
a,p=(a-ra)/2,p*2
|
||||
end
|
||||
return c
|
||||
end
|
||||
|
||||
|
||||
function Xoshiro._rol64(x, k)
|
||||
return Xoshiro._bitwise_or(
|
||||
Xoshiro._bitshift_left(x, k),
|
||||
Xoshiro._bitshift_right(x, 64 - k)
|
||||
)
|
||||
end
|
||||
|
||||
function Xoshiro.random_raw(self)
|
||||
local result = self.state[1] + self.state[4]
|
||||
local t = Xoshiro._bitshift_right(self.state[2], 17)
|
||||
|
||||
self.state[3] = Xoshiro._bitwise_xor(self.state[3], self.state[1])
|
||||
self.state[4] = Xoshiro._bitwise_xor(self.state[4], self.state[2])
|
||||
self.state[2] = Xoshiro._bitwise_xor(self.state[2], self.state[3])
|
||||
self.state[1] = Xoshiro._bitwise_xor(self.state[1], self.state[4])
|
||||
|
||||
self.state[3] = Xoshiro._bitwise_xor(self.state[3], t)
|
||||
self.state[4] = Xoshiro._rol64(self.state[4], 45)
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
function Xoshiro.random(self)
|
||||
return self:random_raw()
|
||||
end
|
||||
|
||||
print("_G", _G)
|
||||
|
||||
for key,value in pairs(_G) do
|
||||
print(key, "→", value)
|
||||
end
|
||||
|
||||
return Xoshiro
|
9
worldeditadditions/utils/random_test.lua
Normal file
9
worldeditadditions/utils/random_test.lua
Normal file
|
@ -0,0 +1,9 @@
|
|||
Xoshiro = require("random")
|
||||
|
||||
rand = Xoshiro.new()
|
||||
|
||||
print(rand)
|
||||
|
||||
for i=1,25 do
|
||||
print(i, "→", rand:random())
|
||||
end
|
Loading…
Reference in a new issue