public void TestForSaltReuse()
        {
            var seen = new HashSet <int>();
            var rng  = new StatelessRng(kSeed);

            StatelessRng.SaltUsed = (salt) => {
                Assert.IsTrue(seen.Add(salt), "Salt {0} is unused", salt);
            };
            try {
                rng.OnUnitCircle(0); seen.Clear();
                rng.InUnitCircle(0); seen.Clear();
                rng.OnUnitSphere(0); seen.Clear();
                rng.InUnitSphere(0); seen.Clear();
                rng.Rotation(0); seen.Clear();
            } finally {
                StatelessRng.SaltUsed = null;
            }
        }
        public void TestUniformity_Rotation()
        {
            var rng = new StatelessRng(kSeed);

            Quaternion[] vals = Gen(i => rng.Rotation(i)).ToArray();

            Func <Quaternion, Vector2> ParametrizeAxisAndAngle = q => {
                Vector3 axis;   // a unit vector
                float   angleRad;
                q.ToAngleAxis(out angleRad, out axis);
                Vector2 param01 = ParametrizeSphereSurfaceThetaZ(axis);
                float   param2  = ToAngle01(angleRad);
                return(new Vector3(param01.x, param01.y, param2));
            };

            S.CheckUniformity(
                new[] { "axis theta", "axis z", "angle" },
                vals.Select(ParametrizeAxisAndAngle));
        }