| //#region src/distribution/internals/uniformIntInternal.ts | |
| /** | |
| * Uniformly generate number in range [0 ; rangeSize[ | |
| * With rangeSize <= 0x100000000 | |
| * @internal | |
| */ | |
| function uniformIntInternal(rng, rangeSize) { | |
| const MaxAllowed = rangeSize > 2 ? ~~(4294967296 / rangeSize) * rangeSize : 4294967296; | |
| let deltaV = rng.next() + 2147483648; | |
| while (deltaV >= MaxAllowed) deltaV = rng.next() + 2147483648; | |
| return deltaV % rangeSize; | |
| } | |
| //#endregion | |
| //#region src/distribution/internals/ArrayInt64.ts | |
| /** | |
| * We only accept safe integers here | |
| * @internal | |
| */ | |
| function fromNumberToArrayInt64(out, n) { | |
| if (n < 0) { | |
| const posN = -n; | |
| out.sign = -1; | |
| out.data[0] = ~~(posN / 4294967296); | |
| out.data[1] = posN >>> 0; | |
| } else { | |
| out.sign = 1; | |
| out.data[0] = ~~(n / 4294967296); | |
| out.data[1] = n >>> 0; | |
| } | |
| return out; | |
| } | |
| /** | |
| * Substract two ArrayInt of 64 bits on 64 bits. | |
| * With arrayIntA - arrayIntB >= 0 | |
| * @internal | |
| */ | |
| function substractArrayInt64(out, arrayIntA, arrayIntB) { | |
| const lowA = arrayIntA.data[1]; | |
| const highA = arrayIntA.data[0]; | |
| const signA = arrayIntA.sign; | |
| const lowB = arrayIntB.data[1]; | |
| const highB = arrayIntB.data[0]; | |
| const signB = arrayIntB.sign; | |
| out.sign = 1; | |
| if (signA === 1 && signB === -1) { | |
| const low = lowA + lowB; | |
| const high = highA + highB + (low > 4294967295 ? 1 : 0); | |
| out.data[0] = high >>> 0; | |
| out.data[1] = low >>> 0; | |
| return out; | |
| } | |
| let lowFirst = lowA; | |
| let highFirst = highA; | |
| let lowSecond = lowB; | |
| let highSecond = highB; | |
| if (signA === -1) { | |
| lowFirst = lowB; | |
| highFirst = highB; | |
| lowSecond = lowA; | |
| highSecond = highA; | |
| } | |
| let reminderLow = 0; | |
| let low = lowFirst - lowSecond; | |
| if (low < 0) { | |
| reminderLow = 1; | |
| low = low >>> 0; | |
| } | |
| out.data[0] = highFirst - highSecond - reminderLow; | |
| out.data[1] = low; | |
| return out; | |
| } | |
| //#endregion | |
| //#region src/distribution/internals/uniformArrayIntInternal.ts | |
| /** | |
| * Uniformly generate ArrayInt64 in range [0 ; rangeSize[ | |
| * | |
| * @remarks | |
| * In the worst case scenario it may discard half of the randomly generated value. | |
| * Worst case being: most significant number is 1 and remaining part evaluates to 0. | |
| * | |
| * @internal | |
| */ | |
| function uniformArrayIntInternal(rng, out, rangeSize) { | |
| const maxIndex0 = rangeSize[0] + 1; | |
| out[0] = uniformIntInternal(rng, maxIndex0); | |
| out[1] = uniformIntInternal(rng, 4294967296); | |
| while (out[0] >= rangeSize[0] && (out[0] !== rangeSize[0] || out[1] >= rangeSize[1])) { | |
| out[0] = uniformIntInternal(rng, maxIndex0); | |
| out[1] = uniformIntInternal(rng, 4294967296); | |
| } | |
| return out; | |
| } | |
| //#endregion | |
| //#region src/distribution/uniformInt.ts | |
| const safeNumberMaxSafeInteger = Number.MAX_SAFE_INTEGER; | |
| const sharedA = { | |
| sign: 1, | |
| data: [0, 0] | |
| }; | |
| const sharedB = { | |
| sign: 1, | |
| data: [0, 0] | |
| }; | |
| const sharedC = { | |
| sign: 1, | |
| data: [0, 0] | |
| }; | |
| const sharedData = [0, 0]; | |
| function uniformLargeIntInternal(rng, from, to, rangeSize) { | |
| const rangeSizeArrayIntValue = rangeSize <= safeNumberMaxSafeInteger ? fromNumberToArrayInt64(sharedC, rangeSize) : substractArrayInt64(sharedC, fromNumberToArrayInt64(sharedA, to), fromNumberToArrayInt64(sharedB, from)); | |
| if (rangeSizeArrayIntValue.data[1] === 4294967295) { | |
| rangeSizeArrayIntValue.data[0] += 1; | |
| rangeSizeArrayIntValue.data[1] = 0; | |
| } else rangeSizeArrayIntValue.data[1] += 1; | |
| uniformArrayIntInternal(rng, sharedData, rangeSizeArrayIntValue.data); | |
| return sharedData[0] * 4294967296 + sharedData[1] + from; | |
| } | |
| /** | |
| * Uniformly generate random integer values between `from` (included) and `to` (included) | |
| * | |
| * @param rng - Instance of RandomGenerator to extract random values from | |
| * @param from - Lower bound of the range (included) | |
| * @param to - Upper bound of the range (included) | |
| * | |
| * @public | |
| */ | |
| function uniformInt(rng, from, to) { | |
| const rangeSize = to - from; | |
| if (rangeSize <= 4294967295) return uniformIntInternal(rng, rangeSize + 1) + from; | |
| return uniformLargeIntInternal(rng, from, to, rangeSize); | |
| } | |
| //#endregion | |
| export { uniformInt }; | |
Xet Storage Details
- Size:
- 3.9 kB
- Xet hash:
- 90b3c50201cfeac4d70db9660d2eeddbf0c1d56c9bd983634c6e2ad6ed9f1246
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.