Files
skills/docs/foundation/random/pseudo-random/src/algorithms/xoshiro256.md
2026-05-29 08:20:56 +01:00

2.1 KiB
Raw Blame History

algorithms/xoshiro256

Purpose

Xoshiro256PlusPlusRng implements Blackman and Vigna's Xoshiro256++ PRNG — 256 bits of state, period 2^256 − 1, with an algebraic jump() that advances the stream by 2^128 steps in O(1) without drawing them. It is the top-of-range SeededRng in this package: use it when you need parallel non-overlapping streams or when simulation runs will be long enough to exhaust SFC32's 2^32 minimum period.

Features

  • 256-bit state (four uint64 words) with a non-zero-state guarantee
  • jump() advances 2^128 draws without intermediate state — ideal for sharding one seed across many workers
  • Checkpoint serialises state as 8 × uint32 pairs, which round-trip through JSON
  • Full SeededRng contract

Usage: Basic Example

import { Xoshiro256PlusPlusRng } from "@suaveplan/pseudo-random";

const rng = new Xoshiro256PlusPlusRng("sim-42");
for (let i = 0; i < 1_000_000; i += 1) rng.nextFloat();

Usage: Advanced Example

import { Xoshiro256PlusPlusRng } from "@suaveplan/pseudo-random";

function streamsForWorkers(base: string, n: number) {
  const rngs: Xoshiro256PlusPlusRng[] = [];
  let r = new Xoshiro256PlusPlusRng(base);
  for (let i = 0; i < n; i += 1) {
    rngs.push(r);
    const next = new Xoshiro256PlusPlusRng(base);
    for (let k = 0; k <= i; k += 1) next.jump();
    r = next;
  }
  return rngs;
}

API Reference

  • new Xoshiro256PlusPlusRng(seed) — splitmix64-expands the seed into 4 × uint64 words.
  • nextUint32() — returns the upper 32 bits of the next uint64 output (better statistical quality than the low bits).
  • jump() — apply the constant-time jump-by-2^128 polynomial.
  • skip / at / fork / checkpoint / restore — SeededRng contract as usual.

Implementation Notes

All 64-bit arithmetic is done with bigint masked to 64 bits. Returning the upper 32 bits of each uint64 step is intentional: Xoshiro's low bits have weaker statistical properties than the high bits. The jump polynomial constants are the canonical published values; the loop processes bit-by-bit, XOR-accumulating the current state whenever the jump polynomial bit is set and then advancing a single step.