Pseudo-random number generator that uses a 16-bits Galois Linear-Feedback Shift Register
cpct_getRandom_glfsr16 | Pseudo-random number generator that uses a 16-bits Galois Linear-Feedback Shift Register |
Functions | |
cpct_getRandom_glfsr16_u8 | Return a pseudo-random byte using Galois Linear-Feedback Shift Register (G-LFSR) method, with a 16-bits state register. |
cpct_getRandom_glfsr16_u16 | Return a pseudo-random 16-bits value using Galois Linear-Feedback Shift Register (G-LFSR) method, with a 16-bits state register. |
Return a pseudo-random byte using Galois Linear-Feedback Shift Register (G-LFSR) method, with a 16-bits state register.
u8 cpct_getRandom_glfsr16_u8 ();
call cpct_getRandom_glfsr16_u8_asm
<u8> | Next 8-bits pseudo-random value. |
This function implements a Galois Linear-Feedback Shift Register with a 16 bits state. This Shift Register does produce 65535 16-bits values without repetition, then cycles again. That is, it is like having the 65536 (excluding 0) possible 16-bits values ordered in a pseudo-random manner, and getting each one at a time.
The implementation of the Shift Register is based on some specific 16-bits values denominated TAPS (Check GLFSR16_TAPSET). These values are bit-masks that select some bits to implement a linear polynomial shifting operation. Depending on the bits selected in the bit-mask, the polynomial implemented changes. There exists 1024 different polynomials that mathematically ensure a 65535-value traversal without repetition. Any other polynomial will have a shorter period. These 1024 TAPSETs that implement the polynomials with full 16-bits traversals are defined in GLFSR16_TAPSET enumeration. Use cpct_setTaps_glfsr16 with any of the these tapsets to select your desired traversal.
Basic use of this function does not require any kind of set-up, just calling the function each time you want a pseudo-random number
// Get next pseudo-random 8-bits number u8 getRandomNumber() { return cpct_getRandom_glfsr16_u8(); }
However, this will return always the same sequence, in the same order. You might consider setting the staring seed at some initialization point,
// Count loops until user presses a key u16 countUntilUserPressesAKey() { u16 loops; do { loops++; cpct_scanKeyboard(); } while ( !cpct_isAnyKeyPressed() ); return loops; } // Initialization code (set initial seed) u16 loops = countUntilUserPressesAKey(); cpct_setSeed_glfsr16(loops);
This code will set the starting state of the internal shift register to a value depending on when the user has pressed a key, which will randomize the starting point in the 65535-values sequence that the pseudo-random generator produces. However, take into account that the 65535-value traversal will be in the same order, unless you changed it calling cpct_setTaps_glfsr16.
AF, HL
22 bytes
Case | microSecs(us) | CPU Cycles ------------------------------------- Best | 19 | 76 ------------------------------------- Worst | 26 | 104 -------------------------------------
This function is based on Galois Linear-Feedback Shift Register method.
Return a pseudo-random 16-bits value using Galois Linear-Feedback Shift Register (G-LFSR) method, with a 16-bits state register.
u16 cpct_getRandom_glfsr16_u16 ();
call cpct_getRandom_glfsr16_u16_asm
<u16> | Next 16-bits pseudo-random value. |
cpct_getRandom_glfsr16_u8, which is the same function.
This function is exactly the same as cpct_getRandom_glfsr16_u8. Both functions share the 100% of their code. The only difference is the return type: cpct_getRandom_glfsr16_u8 returns a u8 (in L register) and cpct_getRandom_glfsr16_u16 returns a u16 (in HL register). So, from C perspective, same code is called, and 16 bits are returned, but sometimes only 8 bits are used (when cpct_getRandom_glfsr16_u8). From assembly point of view, you call the same function, and may decide to use return in L (8 bits) or in HL (16 bits) at your will.