| ... | @@ -60,7 +60,8 @@ pub const Random = struct { | ... | @@ -60,7 +60,8 @@ pub const Random = struct { |
| 60 | /// Constant-time implementation off ::uintLessThan. | 60 | /// Constant-time implementation off ::uintLessThan. |
| 61 | /// The results of this function may be biased. | 61 | /// The results of this function may be biased. |
| 62 | pub fn uintLessThanBiased(r: *Random, comptime T: type, less_than: T) T { | 62 | pub fn uintLessThanBiased(r: *Random, comptime T: type, less_than: T) T { |
| 63 | assert(T.is_signed == false); | 63 | comptime assert(T.is_signed == false); |
| | 64 | comptime assert(T.bit_count <= 64); // TODO: workaround: LLVM ERROR: Unsupported library call operation! |
| 64 | assert(0 < less_than); | 65 | assert(0 < less_than); |
| 65 | // Small is typically u32 | 66 | // Small is typically u32 |
| 66 | const Small = @IntType(false, @divTrunc(T.bit_count + 31, 32) * 32); | 67 | const Small = @IntType(false, @divTrunc(T.bit_count + 31, 32) * 32); |
| ... | @@ -83,7 +84,8 @@ pub const Random = struct { | ... | @@ -83,7 +84,8 @@ pub const Random = struct { |
| 83 | /// this function is guaranteed to return. | 84 | /// this function is guaranteed to return. |
| 84 | /// If you need deterministic runtime bounds, use `::uintLessThanBiased`. | 85 | /// If you need deterministic runtime bounds, use `::uintLessThanBiased`. |
| 85 | pub fn uintLessThan(r: *Random, comptime T: type, less_than: T) T { | 86 | pub fn uintLessThan(r: *Random, comptime T: type, less_than: T) T { |
| 86 | assert(T.is_signed == false); | 87 | comptime assert(T.is_signed == false); |
| | 88 | comptime assert(T.bit_count <= 64); // TODO: workaround: LLVM ERROR: Unsupported library call operation! |
| 87 | assert(0 < less_than); | 89 | assert(0 < less_than); |
| 88 | // Small is typically u32 | 90 | // Small is typically u32 |
| 89 | const Small = @IntType(false, @divTrunc(T.bit_count + 31, 32) * 32); | 91 | const Small = @IntType(false, @divTrunc(T.bit_count + 31, 32) * 32); |
| ... | @@ -431,6 +433,37 @@ fn testRandomIntAtMost() void { | ... | @@ -431,6 +433,37 @@ fn testRandomIntAtMost() void { |
| 431 | assert(r.random.uintAtMost(u0, 0) == 0); | 433 | assert(r.random.uintAtMost(u0, 0) == 0); |
| 432 | } | 434 | } |
| 433 | | 435 | |
| | 436 | test "Random Biased" { |
| | 437 | var r = DefaultPrng.init(0); |
| | 438 | // Not thoroughly checking the logic here. |
| | 439 | // Just want to execute all the paths with different types. |
| | 440 | |
| | 441 | assert(r.random.uintLessThanBiased(u1, 1) == 0); |
| | 442 | assert(r.random.uintLessThanBiased(u32, 10) < 10); |
| | 443 | assert(r.random.uintLessThanBiased(u64, 20) < 20); |
| | 444 | |
| | 445 | assert(r.random.uintAtMostBiased(u0, 0) == 0); |
| | 446 | assert(r.random.uintAtMostBiased(u1, 0) <= 0); |
| | 447 | assert(r.random.uintAtMostBiased(u32, 10) <= 10); |
| | 448 | assert(r.random.uintAtMostBiased(u64, 20) <= 20); |
| | 449 | |
| | 450 | assert(r.random.intRangeLessThanBiased(u1, 0, 1) == 0); |
| | 451 | assert(r.random.intRangeLessThanBiased(i1, -1, 0) == -1); |
| | 452 | assert(r.random.intRangeLessThanBiased(u32, 10, 20) >= 10); |
| | 453 | assert(r.random.intRangeLessThanBiased(i32, 10, 20) >= 10); |
| | 454 | assert(r.random.intRangeLessThanBiased(u64, 20, 40) >= 20); |
| | 455 | assert(r.random.intRangeLessThanBiased(i64, 20, 40) >= 20); |
| | 456 | |
| | 457 | // uncomment for broken module error: |
| | 458 | //assert(r.random.intRangeAtMostBiased(u0, 0, 0) == 0); |
| | 459 | assert(r.random.intRangeAtMostBiased(u1, 0, 1) >= 0); |
| | 460 | assert(r.random.intRangeAtMostBiased(i1, -1, 0) >= -1); |
| | 461 | assert(r.random.intRangeAtMostBiased(u32, 10, 20) >= 10); |
| | 462 | assert(r.random.intRangeAtMostBiased(i32, 10, 20) >= 10); |
| | 463 | assert(r.random.intRangeAtMostBiased(u64, 20, 40) >= 20); |
| | 464 | assert(r.random.intRangeAtMostBiased(i64, 20, 40) >= 20); |
| | 465 | } |
| | 466 | |
| 434 | // Generator to extend 64-bit seed values into longer sequences. | 467 | // Generator to extend 64-bit seed values into longer sequences. |
| 435 | // | 468 | // |
| 436 | // The number of cycles is thus limited to 64-bits regardless of the engine, but this | 469 | // The number of cycles is thus limited to 64-bits regardless of the engine, but this |