Skip to content

Commit 0ed2495

Browse files
committed
add uint32_max, uint64_max, uint128_max and uint_max procs to math/rand
1 parent f48e87d commit 0ed2495

File tree

1 file changed

+160
-0
lines changed

1 file changed

+160
-0
lines changed

core/math/rand/rand.odin

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,166 @@ int_max :: proc(n: int, gen := context.random_generator) -> (val: int) {
359359
}
360360
}
361361

362+
/*
363+
Generates a random 32 bit value in the range `[0, n)` using the provided random number generator. If no generator is provided the global random number generator will be used.
364+
365+
Inputs:
366+
- n: The upper bound of the generated number, this value is exclusive
367+
368+
Returns:
369+
- val: A random 32 bit value in the range `[0, n)`
370+
371+
WARNING: Panics if n is equal to 0
372+
373+
Example:
374+
import "core:math/rand"
375+
import "core:fmt"
376+
377+
uint32_max_example :: proc() {
378+
fmt.println(rand.uint32_max(16))
379+
}
380+
381+
Possible Output:
382+
383+
6
384+
13
385+
386+
*/
387+
@(require_results)
388+
uint32_max :: proc(n: u32, gen := context.random_generator) -> (val: u32) {
389+
if n == 0 {
390+
panic("Invalid argument to uint32_max")
391+
}
392+
if n & (n - 1) == 0 {
393+
return uint32(gen) & (n - 1)
394+
}
395+
min := (-n) % n
396+
v := uint32(gen)
397+
for v < min {
398+
v = uint32(gen)
399+
}
400+
return v % n
401+
}
402+
403+
/*
404+
Generates a random 64 bit value in the range `[0, n)` using the provided random number generator. If no generator is provided the global random number generator will be used.
405+
406+
Inputs:
407+
- n: The upper bound of the generated number, this value is exclusive
408+
409+
Returns:
410+
- val: A random 64 bit value in the range `[0, n)`
411+
412+
WARNING: Panics if n is equal to 0
413+
414+
Example:
415+
import "core:math/rand"
416+
import "core:fmt"
417+
418+
uint64_max_example :: proc() {
419+
fmt.println(rand.uint64_max(16))
420+
}
421+
422+
Possible Output:
423+
424+
6
425+
13
426+
427+
*/
428+
@(require_results)
429+
uint64_max :: proc(n: u64, gen := context.random_generator) -> (val: u64) {
430+
if n == 0 {
431+
panic("Invalid argument to uint64_max")
432+
}
433+
if n & (n - 1) == 0 {
434+
return uint64(gen) & (n - 1)
435+
}
436+
min := (-n) % n
437+
v := uint64(gen)
438+
for v < min {
439+
v = uint64(gen)
440+
}
441+
return v % n
442+
}
443+
444+
/*
445+
Generates a random 128 bit value in the range `[0, n)` using the provided random number generator. If no generator is provided the global random number generator will be used.
446+
447+
Inputs:
448+
- n: The upper bound of the generated number, this value is exclusive
449+
450+
Returns:
451+
- val: A random 128 bit value in the range `[0, n)`
452+
453+
WARNING: Panics if n is equal to 0
454+
455+
Example:
456+
import "core:math/rand"
457+
import "core:fmt"
458+
459+
uint128_max_example :: proc() {
460+
fmt.println(rand.uint128_max(16))
461+
}
462+
463+
Possible Output:
464+
465+
6
466+
13
467+
468+
*/
469+
@(require_results)
470+
uint128_max :: proc(n: u128, gen := context.random_generator) -> (val: u128) {
471+
if n == 0 {
472+
panic("Invalid argument to uint128_max")
473+
}
474+
if n & (n - 1) == 0 {
475+
return uint128(gen) & (n - 1)
476+
}
477+
min := (-n) % n
478+
v := uint128(gen)
479+
for v < min {
480+
v = uint128(gen)
481+
}
482+
return v % n
483+
}
484+
485+
/*
486+
Generates a random integer value in the range `[0, n)` using the provided random number generator. If no generator is provided the global random number generator will be used.
487+
488+
Inputs:
489+
- n: The upper bound of the generated number, this value is exclusive
490+
491+
Returns:
492+
- val: A random integer value in the range `[0, n)`
493+
494+
WARNING: Panics if n is equal to 0
495+
496+
Example:
497+
import "core:math/rand"
498+
import "core:fmt"
499+
500+
uint_max_example :: proc() {
501+
fmt.println(rand.uint_max(16))
502+
}
503+
504+
Possible Output:
505+
506+
6
507+
13
508+
509+
*/
510+
@(require_results)
511+
uint_max :: proc(n: uint, gen := context.random_generator) -> (val: uint) {
512+
if n <= 0 {
513+
panic("Invalid argument to uint_max")
514+
}
515+
when size_of(int) == 4 {
516+
return uint(uint32_max(u32(n), gen))
517+
} else {
518+
return uint(uint64_max(u64(n), gen))
519+
}
520+
}
521+
362522
/*
363523
Generates a random double floating point value in the range `[0, 1)` using the provided random number generator. If no generator is provided the global random number generator will be used.
364524

0 commit comments

Comments
 (0)