--- Comment #1 from wgh at beyondunreal dot com ---
The loop in question looks like this, in C++ and aseembly:

        if (__urngrange > __urange)
            // downscaling
            const __uctype __uerange = __urange + 1; // __urange can be zero
            const __uctype __scaling = __urngrange / __uerange;
            const __uctype __past = __uerange * __scaling;
              __ret = __uctype(__urng()) - __urngmin;
            while (__ret >= __past);
            __ret /= __scaling;

 80001f4:       f7ff ffda       bl      80001ac
 80001f8:       1e43            subs    r3, r0, #1
 80001fa:       429c            cmp     r4, r3
 80001fc:       d9fa            bls.n   80001f4

So LCG has been greatly optimized and has become a single __calc call.
gdb shows some extra "fake" frames, even though they have been optimized out.

#0  __calc (__x=0) at
#1  0x080001f8 in std::__detail::__mod<unsigned int, 2147483647u, 48271u,
0u>(unsigned int) ()
#2  operator() (this=0x20000430 <random_engine>) at
#3  operator() (this=this@entry=0x2001ffd0, __param=..., __urng=...)
#4  0x080002be in operator() (__urng=..., this=0x2001ffd0) at

The __calc function looks like this in assembly:
080001ac <_ZNSt8__detail4_ModIjLj2147483647ELj48271ELj0ELb0ELb1EE6__calcEj>:
 80001ac:       f64a 52c8       movw    r2, #44488      ; 0xadc8
 80001b0:       fbb0 f1f2       udiv    r1, r0, r2
 80001b4:       fb02 0311       mls     r3, r2, r1, r0
 80001b8:       f64b 428f       movw    r2, #48271      ; 0xbc8f
 80001bc:       4353            muls    r3, r2
 80001be:       f640 5247       movw    r2, #3399       ; 0xd47
 80001c2:       fb02 f001       mul.w   r0, r2, r1
 80001c6:       4283            cmp     r3, r0
 80001c8:       bf3c            itt     cc
 80001ca:       f103 4300       addcc.w r3, r3, #2147483648     ; 0x80000000
 80001ce:       f103 33ff       addcc.w r3, r3, #4294967295     ; 0xffffffff
 80001d2:       1a18            subs    r0, r3, r0
 80001d4:       4770            bx      lr

It should calculate x = (ax + c) mod m, where a = 48271u, c = 0u, m =

So in case of x=0, new x will also be zero. Hmm, sounds weird.

Reply via email to