Skip to content

Commit

Permalink
💥 BREAKING CHANGE: Move to more functional API.
Browse files Browse the repository at this point in the history
  • Loading branch information
make-github-pseudonymous-again committed Dec 7, 2020
1 parent 6e74f3f commit 18bd143
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 37 deletions.
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@
Pseudorandom number generators for JavaScript.
See [docs](https://aureooms.github.io/js-pseudo-random/index.html).

> :warning: The code requires `regeneratorRuntime` to be defined, for instance by importing
> [regenerator-runtime/runtime](https://www.npmjs.com/package/regenerator-runtime).
```js
import {SplitMix64} from '@aureooms/js-pseudo-random';
import {
splitmix64,
nextFloat,
nextUint64,
} from '@aureooms/js-pseudo-random';

const seed = [0, 0]; // Two 32-bit signed integers.
const prng = new SplitMix64(seed);
prng.next(); // 64 random bits as two 32-bit signed integers.
prng.nextFloat(); // a random float in the range [0, 1[
const prng = splitmix64(seed);
nextUint64(prng); // 64 random bits as two 32-bit signed integers (compatible with @aureooms/js-uint64).
nextFloat(prng); // A random float in the range [0, 1[.
```

[![License](https://img.shields.io/github/license/aureooms/js-pseudo-random.svg)](https://raw.githubusercontent.com/aureooms/js-pseudo-random/main/LICENSE)
Expand Down
12 changes: 11 additions & 1 deletion doc/manual/usage.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
# Usage

Import the library where needed
> :warning: The code requires `regeneratorRuntime` to be defined, for instance by importing
> [regenerator-runtime/runtime](https://www.npmjs.com/package/regenerator-runtime).
First, require the polyfill at the entry point of your application
```js
require( 'regenerator-runtime/runtime' );
// or
import 'regenerator-runtime/runtime.js' ;
```

Then, import the library where needed
```js
const pseudorandom = require( '@aureooms/js-pseudo-random' ) ;
// or
Expand Down
20 changes: 0 additions & 20 deletions src/SplitMix64.js

This file was deleted.

10 changes: 7 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import SplitMix64 from './SplitMix64';
import nextFloat from './nextFloat';
import nextUint64 from './nextUint64';
import splitmix64 from './splitmix64';

/* eslint import/no-anonymous-default-export: [2, {"allowObject": true}] */
export default {
SplitMix64,
nextFloat,
nextUint64,
splitmix64,
};

export {SplitMix64};
export {nextFloat, nextUint64, splitmix64};
5 changes: 5 additions & 0 deletions src/nextFloat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default function nextFloat(prng) {
const a = prng.next().value;
const b = prng.next().value;
return (a >>> 0) / 2 ** 32 + (b >>> 0) / 2 ** 64;
}
3 changes: 3 additions & 0 deletions src/nextUint64.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function nextUint64(prng) {
return [prng.next().value, prng.next().value];
}
12 changes: 12 additions & 0 deletions src/splitmix64.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {add64, mul64, xor64, shr64, get64} from '@aureooms/js-uint64';

export default function* splitmix64(seed) {
let state = get64(...seed);
while (true) {
state = add64(state, get64(0x9e3779b9, 0x7f4a7c15));
let z = state;
z = mul64(xor64(z, shr64(z, 30)), get64(0xbf58476d, 0x1ce4e5b9));
z = mul64(xor64(z, shr64(z, 27)), get64(0x94d049bb, 0x133111eb));
yield* xor64(z, shr64(z, 31));
}
}
18 changes: 9 additions & 9 deletions test/src/SplitMix64.js → test/src/splitmix64.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import test from 'ava';
import {range, map} from '@aureooms/js-itertools';

import {SplitMix64} from '../../src';
import {splitmix64, nextUint64, nextFloat} from '../../src';

test('https://rosettacode.org/wiki/Pseudo-random_numbers/Splitmix64 #1', (t) => {
/**
* Show the first five integers generated using the seed 1234567.
*/
const seed = [0, 1234567];
const prng = new SplitMix64(seed);
t.deepEqual(prng.next(), [0x599ed017 | 0, 0xfb08fc85 | 0]); // 6457827717110365317
t.deepEqual(prng.next(), [0x2c73f084 | 0, 0x58540fa5 | 0]); // 3203168211198807973
t.deepEqual(prng.next(), [0x883ebce5 | 0, 0xa3f27c77 | 0]); // 9817491932198370423
t.deepEqual(prng.next(), [0x3fbef740 | 0, 0xe9177b3f | 0]); // 4593380528125082431
t.deepEqual(prng.next(), [0xe3b83467 | 0, 0x08cb5ecd | 0]); // 16408922859458223821
const prng = splitmix64(seed);
t.deepEqual(nextUint64(prng), [0x599ed017 | 0, 0xfb08fc85 | 0]); // 6457827717110365317
t.deepEqual(nextUint64(prng), [0x2c73f084 | 0, 0x58540fa5 | 0]); // 3203168211198807973
t.deepEqual(nextUint64(prng), [0x883ebce5 | 0, 0xa3f27c77 | 0]); // 9817491932198370423
t.deepEqual(nextUint64(prng), [0x3fbef740 | 0, 0xe9177b3f | 0]); // 4593380528125082431
t.deepEqual(nextUint64(prng), [0xe3b83467 | 0, 0x08cb5ecd | 0]); // 16408922859458223821
});

test('https://rosettacode.org/wiki/Pseudo-random_numbers/Splitmix64 #2', (t) => {
Expand All @@ -25,10 +25,10 @@ test('https://rosettacode.org/wiki/Pseudo-random_numbers/Splitmix64 #2', (t) =>
*/

const seed = [0, 987654321];
const prng = new SplitMix64(seed);
const prng = splitmix64(seed);
const histogram = new Array(5).fill(0);
for (const k of map(
() => Math.floor(prng.nextFloat() * 5) | 0,
() => Math.floor(nextFloat(prng) * 5) | 0,
range(100000),
)) {
++histogram[k];
Expand Down

0 comments on commit 18bd143

Please sign in to comment.