mirror of
https://github.com/open-goal/jak-project.git
synced 2024-10-20 11:26:18 -04:00
RNG - mimic Java's Util.Random (#1672)
* initial java Util.Random mimic * add comment referencing java impl * fix 64 bit stuff * copy scf-time definition into math.gc, use for initial seed * rename java -> knuth * move knuth-rand to separate file * move knuth-rand to separate file * PR comments
This commit is contained in:
parent
d53f0ccd35
commit
a04bdff80d
|
@ -6287,7 +6287,6 @@
|
|||
:flag-assert #x900000008
|
||||
)
|
||||
|
||||
|
||||
;; ----------------------
|
||||
;; File - capture
|
||||
;; Source Path - engine/gfx/capture.gc
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
("connect.o" "connect")
|
||||
("text-h.o" "text-h")
|
||||
("settings-h.o" "settings-h")
|
||||
("knuth-rand.o" "knuth-rand") ;; added
|
||||
("capture.o" "capture")
|
||||
("memory-usage-h.o" "memory-usage-h")
|
||||
("texture.o" "texture")
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
("connect.o" "connect")
|
||||
("text-h.o" "text-h")
|
||||
("settings-h.o" "settings-h")
|
||||
("knuth-rand.o" "knuth-rand") ;; added
|
||||
("capture.o" "capture")
|
||||
("memory-usage-h.o" "memory-usage-h")
|
||||
("texture.o" "texture")
|
||||
|
|
|
@ -233,3 +233,21 @@
|
|||
)
|
||||
|
||||
(define-extern *setting-control* setting-control)
|
||||
|
||||
(defun scf-time-to-uint64 ()
|
||||
(let ((date (new 'stack 'scf-time)))
|
||||
(let ((temp (the uint64 0)))
|
||||
(scf-get-time date)
|
||||
|
||||
(logior! temp (-> date stat))
|
||||
(logior! temp (shl (-> date second) 8))
|
||||
(logior! temp (shl (-> date minute) 16))
|
||||
(logior! temp (shl (-> date hour) 24))
|
||||
(logior! temp (shl (-> date week) 32))
|
||||
(logior! temp (shl (-> date day) 40))
|
||||
(logior! temp (shl (-> date month) 48))
|
||||
(logior! temp (shl (-> date year) 56))
|
||||
temp
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
71
goal_src/jak1/engine/math/knuth-rand.gc
Normal file
71
goal_src/jak1/engine/math/knuth-rand.gc
Normal file
|
@ -0,0 +1,71 @@
|
|||
;;-*-Lisp-*-
|
||||
(in-package goal)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;; mimicking Java's util.Random https://docs.oracle.com/javase/8/docs/api/java/util/Random.html
|
||||
;;;; This is a linear congruential pseudorandom number generator, as defined by D. H. Lehmer
|
||||
;;;; and described by Donald E. Knuth in The Art of Computer Programming, Volume 3: Seminumerical Algorithms, section 3.2.1.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
(deftype knuth-rand-state (structure)
|
||||
((seed uint64))
|
||||
)
|
||||
|
||||
(define *knuth-rand-state* (new 'global 'knuth-rand-state))
|
||||
|
||||
(defun knuth-rand-init ((newSeed uint))
|
||||
(set! (-> *knuth-rand-state* seed) newSeed)
|
||||
)
|
||||
(knuth-rand-init (scf-time-to-uint64))
|
||||
|
||||
(defun knuth-rand-advance-seed ()
|
||||
;; seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1)
|
||||
(set! (-> *knuth-rand-state* seed) (the uint64 (logand (+ (imul64 (-> *knuth-rand-state* seed) 25214903917) 11) (- (shl 1 48) 1))))
|
||||
)
|
||||
|
||||
(defun knuth-rand-next ((bits int))
|
||||
(knuth-rand-advance-seed)
|
||||
|
||||
;; return (int)(seed >>> (48 - bits))
|
||||
(shr (-> *knuth-rand-state* seed) (- 48 bits))
|
||||
)
|
||||
|
||||
(defun knuth-rand-nextInt ()
|
||||
(knuth-rand-advance-seed)
|
||||
(-> *knuth-rand-state* seed)
|
||||
)
|
||||
|
||||
;; returns a pseudorandom int in the range [min, max)
|
||||
(defun knuth-rand-nextIntRange ((min int) (max int))
|
||||
(let* ((bound (- max min))
|
||||
;; int bits, val;
|
||||
(bits (the uint64 0))
|
||||
(val (the uint64 0)))
|
||||
|
||||
;; if ((bound & -bound) == bound) // i.e., bound is a power of 2
|
||||
(if (= (logand bound (* -1 bound)) bound)
|
||||
;; return (int)((bound * (long)next(31)) >> 31);
|
||||
(return (sar (* bound (knuth-rand-next 31)) 31))
|
||||
)
|
||||
|
||||
;; do {
|
||||
;; bits = next(31);
|
||||
;; val = bits % bound;
|
||||
;; } while (bits - val + (bound-1) < 0);
|
||||
;; return val;
|
||||
(while #t
|
||||
(set! bits (knuth-rand-next 31))
|
||||
(set! val (mod bits bound))
|
||||
|
||||
(if (>= (+ bits (* -1 val) bound -1) 0)
|
||||
(return (+ min val))
|
||||
)
|
||||
)
|
||||
)
|
||||
-1
|
||||
)
|
||||
|
||||
;; returns a pseudorandom float in the range [0, 1)
|
||||
(defun knuth-rand-nextFloat ()
|
||||
;; return next(24) / ((float)(1 << 24));
|
||||
(/ (the float (knuth-rand-next 24)) (shl 1 24))
|
||||
)
|
|
@ -315,5 +315,4 @@
|
|||
(defmacro rand-float-gen (&key (gen *random-generator*))
|
||||
"Generate a float from [0, 1)"
|
||||
`(+ -1.0 (the-as float (logior #x3f800000 (/ (rand-uint31-gen ,gen) 256))))
|
||||
)
|
||||
|
||||
)
|
|
@ -1696,6 +1696,7 @@
|
|||
"engine/connect.gc"
|
||||
"ui/text-h.gc"
|
||||
"game/settings-h.gc"
|
||||
"math/knuth-rand.gc" ;; added
|
||||
"util/capture.gc"
|
||||
"debug/memory-usage-h.gc"
|
||||
"gfx/texture/texture.gc"
|
||||
|
|
Loading…
Reference in a new issue