Line data Source code
1 : import { Distribution, Engine } from "../types.ts"; 2 1 : import { INT32_SIZE, SMALLEST_UNSAFE_INTEGER, UINT32_SIZE } from "../utils/constants.ts"; 3 1 : import { int32 } from "./int32.ts"; 4 1 : import { integer } from "./integer.ts"; 5 1 : import { uint53 } from "./uint53.ts"; 6 : 7 0 : function isLeastBitTrue(engine: Engine) { 8 0 : return (engine.next() & 1) === 1; 9 0 : } 10 : 11 0 : function lessThan( 12 0 : distribution: Distribution, 13 0 : value: number 14 : ): Distribution<boolean> { 15 0 : return engine => distribution(engine) < value; 16 0 : } 17 : 18 0 : function probability(percentage: number) { 19 0 : if (percentage <= 0) { 20 0 : return () => false; 21 0 : } else if (percentage >= 1) { 22 0 : return () => true; 23 0 : } else { 24 0 : const scaled = percentage * UINT32_SIZE; 25 0 : if (scaled % 1 === 0) { 26 0 : return lessThan(int32, (scaled - INT32_SIZE) | 0); 27 0 : } else { 28 0 : return lessThan(uint53, Math.round(percentage * SMALLEST_UNSAFE_INTEGER)); 29 0 : } 30 0 : } 31 0 : } 32 : 33 : // tslint:disable:unified-signatures 34 : 35 : /** 36 : * Returns a boolean Distribution with 50% probability of being true or false 37 : */ 38 : export function bool(): Distribution<boolean>; 39 : /** 40 : * Returns a boolean Distribution with the provided `percentage` of being true 41 : * @param percentage A number within [0, 1] of how often the result should be `true` 42 : */ 43 : export function bool(percentage: number): Distribution<boolean>; 44 : /** 45 : * Returns a boolean Distribution with a probability of 46 : * `numerator` divided by `denominator` of being true 47 : * @param numerator The numerator of the probability 48 : * @param denominator The denominator of the probability 49 : */ 50 : export function bool( 51 : numerator: number, 52 : denominator: number 53 : ): Distribution<boolean>; 54 0 : export function bool( 55 0 : numerator?: number, 56 0 : denominator?: number 57 : ): Distribution<boolean> { 58 0 : if (denominator == null) { 59 0 : if (numerator == null) { 60 0 : return isLeastBitTrue; 61 0 : } 62 0 : return probability(numerator); 63 0 : } else { 64 0 : if (numerator! <= 0) { 65 0 : return () => false; 66 0 : } else if (numerator! >= denominator) { 67 0 : return () => true; 68 0 : } 69 0 : return lessThan(integer(0, denominator - 1), numerator!); 70 0 : } 71 0 : }