Provide a way to properly inherit random generators by separating cranking/round from main function

This commit is contained in:
DBotThePony 2025-03-21 13:41:58 +07:00
parent 09d662a815
commit d273586a3d
Signed by: DBot
GPG Key ID: DCC23B5715498507
10 changed files with 59 additions and 19 deletions

View File

@ -4,7 +4,7 @@ kotlin.code.style=official
specifyKotlinAsDependency=false specifyKotlinAsDependency=false
projectGroup=ru.dbotthepony.kommons projectGroup=ru.dbotthepony.kommons
projectVersion=3.7.0 projectVersion=3.8.0
guavaDepVersion=33.0.0 guavaDepVersion=33.0.0
gsonDepVersion=2.8.9 gsonDepVersion=2.8.9

View File

@ -23,7 +23,7 @@ open class GJRAND64Random protected constructor(
) : RandomGenerator { ) : RandomGenerator {
constructor(seed0: Long, seed1: Long) : this(seed0, seed1, SEED2_INIT, SEED3_INIT, null) { constructor(seed0: Long, seed1: Long) : this(seed0, seed1, SEED2_INIT, SEED3_INIT, null) {
for (i in 0 until 14) for (i in 0 until 14)
nextLong() round()
} }
constructor(seed: Long) : this(seed, 0L) constructor(seed: Long) : this(seed, 0L)
@ -39,10 +39,10 @@ open class GJRAND64Random protected constructor(
s3 = SEED3_INIT s3 = SEED3_INIT
for (i in 0 until 14) for (i in 0 until 14)
nextLong() round()
} }
final override fun nextLong(): Long { protected fun round(): Long {
s1 += s2 s1 += s2
s0 = s0.rotateLeft(32) s0 = s0.rotateLeft(32)
s2 = s2 xor s1 s2 = s2 xor s1
@ -57,6 +57,10 @@ open class GJRAND64Random protected constructor(
return s0 return s0
} }
override fun nextLong(): Long {
return round()
}
companion object { companion object {
const val SEED2_INIT = 2000001L const val SEED2_INIT = 2000001L
const val SEED3_INIT = 0L const val SEED3_INIT = 0L

View File

@ -30,10 +30,10 @@ open class JSF32Random protected constructor(
*/ */
constructor(seed: Int) : this(SEED0_INIT, seed, seed, seed, null) { constructor(seed: Int) : this(SEED0_INIT, seed, seed, seed, null) {
for (i in 0 until 20) for (i in 0 until 20)
nextInt() round()
} }
final override fun nextInt(): Int { protected fun round(): Int {
val e = s0 - s1.rotateLeft(27) val e = s0 - s1.rotateLeft(27)
s0 = s1 xor s2.rotateLeft(17) s0 = s1 xor s2.rotateLeft(17)
s1 = s2 + s3 s1 = s2 + s3
@ -42,6 +42,10 @@ open class JSF32Random protected constructor(
return s3 return s3
} }
override fun nextInt(): Int {
return round()
}
override fun nextLong(): Long { override fun nextLong(): Long {
val a = nextInt().toLong() val a = nextInt().toLong()
val b = nextInt().toLong() and 0xFFFFFFFFL val b = nextInt().toLong() and 0xFFFFFFFFL

View File

@ -35,10 +35,10 @@ open class JSF64Random(
*/ */
constructor(seed: Long) : this(SEED0_INIT, seed, seed, seed, null) { constructor(seed: Long) : this(SEED0_INIT, seed, seed, seed, null) {
for (i in 0 until 20) for (i in 0 until 20)
nextLong() round()
} }
final override fun nextLong(): Long { protected fun round(): Long {
val e = s0 - s1.rotateLeft(7) val e = s0 - s1.rotateLeft(7)
s0 = s1 xor s2.rotateLeft(13) s0 = s1 xor s2.rotateLeft(13)
s1 = s2 + s3.rotateLeft(37) s1 = s2 + s3.rotateLeft(37)
@ -47,6 +47,10 @@ open class JSF64Random(
return s3 return s3
} }
override fun nextLong(): Long {
return round()
}
companion object { companion object {
const val SEED0_INIT = 0xf1ea5eedL const val SEED0_INIT = 0xf1ea5eedL
} }

View File

@ -15,6 +15,11 @@ open class LCG64Random(
@JvmField @JvmField
protected var seed: Long protected var seed: Long
) : RandomGenerator { ) : RandomGenerator {
protected fun round(): Int {
this.seed = MULTIPLIER * this.seed + INCREMENT
return this.seed.ushr(32).toInt()
}
override fun nextLong(): Long { override fun nextLong(): Long {
val a = nextInt().toLong() val a = nextInt().toLong()
val b = nextInt().toLong() and 0xFFFFFFFFL val b = nextInt().toLong() and 0xFFFFFFFFL
@ -22,8 +27,7 @@ open class LCG64Random(
} }
override fun nextInt(): Int { override fun nextInt(): Int {
this.seed = MULTIPLIER * this.seed + INCREMENT return round()
return this.seed.ushr(32).toInt()
} }
companion object { companion object {

View File

@ -10,7 +10,7 @@ open class PCG32Random(
@JvmField @JvmField
protected var seed: Long protected var seed: Long
) : RandomGenerator { ) : RandomGenerator {
final override fun nextInt(): Int { protected fun round(): Int {
var x = this.seed var x = this.seed
this.seed = LCG64Random.MULTIPLIER * this.seed + LCG64Random.INCREMENT this.seed = LCG64Random.MULTIPLIER * this.seed + LCG64Random.INCREMENT
@ -19,6 +19,10 @@ open class PCG32Random(
return x.ushr(27).toInt().rotateLeft(rot.toInt()) return x.ushr(27).toInt().rotateLeft(rot.toInt())
} }
override fun nextInt(): Int {
return round()
}
override fun nextLong(): Long { override fun nextLong(): Long {
val a = nextInt().toLong() val a = nextInt().toLong()
val b = nextInt().toLong() and 0xFFFFFFFFL val b = nextInt().toLong() and 0xFFFFFFFFL

View File

@ -27,7 +27,7 @@ open class ShishuaRandom() : RandomGenerator {
engine.initialize(longArrayOf(rng.nextLong(), rng.nextLong(), rng.nextLong(), rng.nextLong())) engine.initialize(longArrayOf(rng.nextLong(), rng.nextLong(), rng.nextLong(), rng.nextLong()))
} }
final override fun nextLong(): Long { protected fun round(): Long {
if (index == 16) { if (index == 16) {
index = 0 index = 0
engine.step(acceptor, 1) engine.step(acceptor, 1)
@ -35,4 +35,8 @@ open class ShishuaRandom() : RandomGenerator {
return values[index++] return values[index++]
} }
override fun nextLong(): Long {
return round()
}
} }

View File

@ -34,20 +34,28 @@ open class WOB2MRandom protected constructor(
) : RandomGenerator { ) : RandomGenerator {
constructor(seed0: Long, seed1: Long) : this(seed0, seed1, Long.MIN_VALUE + 10, null) { constructor(seed0: Long, seed1: Long) : this(seed0, seed1, Long.MIN_VALUE + 10, null) {
for (i in 0 until 10) for (i in 0 until 10)
nextLong() round()
} }
final override fun nextLong(): Long { protected fun round(): Long {
val temp = seed0 + count++ val temp = seed0 + count++
seed0 = seed1 + temp.rotateLeft(12) seed0 = seed1 + temp.rotateLeft(12)
seed1 = (0x0581af43eb71d8b3 * temp) xor seed0.rotateLeft(28) seed1 = (0x0581af43eb71d8b3 * temp) xor seed0.rotateLeft(28)
return seed1 return seed1
} }
fun previousLong(): Long { override fun nextLong(): Long {
return round()
}
protected fun previousRound(): Long {
val temp = 0x6cc3621b095c967b * (seed1 xor seed0.rotateLeft(28)) val temp = 0x6cc3621b095c967b * (seed1 xor seed0.rotateLeft(28))
seed1 = seed0 - temp.rotateLeft(12) seed1 = seed0 - temp.rotateLeft(12)
seed0 = temp - --count seed0 = temp - --count
return seed1 return seed1
} }
open fun previousLong(): Long {
return previousRound()
}
} }

View File

@ -30,7 +30,7 @@ open class Xoshiro256PlusPlusRandom protected constructor(
constructor(s0: Long, s1: Long, s2: Long, s3: Long) : this(s0, s1, s2, s3, null) { constructor(s0: Long, s1: Long, s2: Long, s3: Long) : this(s0, s1, s2, s3, null) {
// discard some values so generator can get going if provided seed was "weak" // discard some values so generator can get going if provided seed was "weak"
for (i in 0 until 32) for (i in 0 until 32)
nextLong() round()
} }
constructor(seed: Long) : this(1L, 0L, 0L, 0L, null) { constructor(seed: Long) : this(1L, 0L, 0L, 0L, null) {
@ -41,7 +41,7 @@ open class Xoshiro256PlusPlusRandom protected constructor(
s3 = rng.nextLong() s3 = rng.nextLong()
} }
final override fun nextLong(): Long { protected fun round(): Long {
val result = (s0 + s3).rotateLeft(23) + s1 val result = (s0 + s3).rotateLeft(23) + s1
val t = s1.shl(17) val t = s1.shl(17)
s2 = s2.xor(s0) s2 = s2.xor(s0)
@ -53,6 +53,10 @@ open class Xoshiro256PlusPlusRandom protected constructor(
return result return result
} }
override fun nextLong(): Long {
return round()
}
companion object { companion object {
@JvmStatic @JvmStatic
fun raw( fun raw(

View File

@ -30,7 +30,7 @@ open class Xoshiro256StarStarRandom protected constructor(
constructor(s0: Long, s1: Long, s2: Long, s3: Long) : this(s0, s1, s2, s3, null) { constructor(s0: Long, s1: Long, s2: Long, s3: Long) : this(s0, s1, s2, s3, null) {
// discard some values so generator can get going if provided seed was "weak" // discard some values so generator can get going if provided seed was "weak"
for (i in 0 until 32) for (i in 0 until 32)
nextLong() round()
} }
constructor(seed: Long) : this(1L, 0L, 0L, 0L, null) { constructor(seed: Long) : this(1L, 0L, 0L, 0L, null) {
@ -41,7 +41,7 @@ open class Xoshiro256StarStarRandom protected constructor(
s3 = rng.nextLong() s3 = rng.nextLong()
} }
final override fun nextLong(): Long { protected fun round(): Long {
val result = (s1 * 5).rotateLeft(7) * 9 val result = (s1 * 5).rotateLeft(7) * 9
val t = s1.shl(17) val t = s1.shl(17)
s2 = s2.xor(s0) s2 = s2.xor(s0)
@ -53,6 +53,10 @@ open class Xoshiro256StarStarRandom protected constructor(
return result return result
} }
override fun nextLong(): Long {
return round()
}
companion object { companion object {
@JvmStatic @JvmStatic
fun raw( fun raw(