News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Pseudo Random Numbers

Started by tda0626, June 04, 2024, 09:06:52 AM

Previous topic - Next topic

tda0626

For my line drawing program, I would like to generate some random coordinates but I am not sure on how to make a RNG. I read online that the function for a LCG is defined as

Xn+1 = ( A*Xn + C) mod M

Where

M > 0
A>0 and A<M
C>=0 and C<M
Seed>=0 and Seed<M

What I am not sure about is what the A and C should be. I tried to understand the math gobbledygook but really don't have the time nor the inclination to do a deep dive into random number theory. Is there a simpler way or maybe someone could maybe explain it to me in a better fashion?

I am working in 320 x 200 mode so my random coordinates need to be in that range.

Tim






tda0626

I came across a Linear Feedback Shift Register RNG and it seemed simple enough to implement and seems to work ok. However, when I pass the values to my PlotLine function, it only draws a single random pixel. I ran it through a debugger and it seems to pass the values to PlotLine correctly. If I pass the values generated by my RNG as a constant to PlotLine, it draws the line fine so I am unsure why it is not working properly. I have attached my source code and program if someone wants to take a look at it to see if they spot what is happening.

RNG Code
RNDNumber proc modulus:word
       
        mov ah, 0
        int 1ah
        ;     LFSR routine
        ;   ------------
        ;    1. Seed value
        ;    2. XOR bits 0 and 1 of the Seed
        ;    3. Shift seed right by 1
        ;    4. Add result 2. to most significant bit after shifting seed
        ;    5. Divide by modulus
        ;    6. Move remainder in AX as return value
       
        mov ax, dx    ; save dx
        mov cx, dx    ; create a copy of dx
        and cx, 1    ; clear bits except bit 0   
        and dx, 2    ; clear bits except bit 1
        shr dx, 1    ; shift dx right by 1 to XOR bits in cx and dx
        xor cx, dx    ; XOR bits
        shl cx, 15    ; set most significant bit
        shr ax, 1    ; shift ax right by 1
        xor ax, cx    ; XOR to set most significant bit
        div modulus
        mov ax, dx
       
        ret
RNDNumber endp

 

NoCforMe

Well, since the RNG code looks OK (and even if it doesn't work it shouldn't matter, as it's just returning a value in AX anyhow), the problem must be in how you're passing this value to your line-drawing routine. You say it works if you pass a constant value: are you sure you're passing x- and y-coordinates correctly?
Assembly language programming should be fun. That's why I do it.

sinsi

How often do you call the generator? INT 1A returns the low tick count in DX, but the tick count is only updated 18.2 times per second. If you are too quick, you will get the same value in DX since the timer wasn't triggered.

daydreamer

Simplest RNG used in infinished Perkin noise
https://masm32.com/board/index.php?topic=7324.0
Fast low quality RNG
my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

tda0626

Quote from: NoCforMe on June 04, 2024, 02:29:07 PMWell, since the RNG code looks OK (and even if it doesn't work it shouldn't matter, as it's just returning a value in AX anyhow), the problem must be in how you're passing this value to your line-drawing routine. You say it works if you pass a constant value: are you sure you're passing x- and y-coordinates correctly?

In debug, it is storing the lx1, ly1, lx2, ly2 in memory after RNDNumber returns and then when I call PlotLine, it shows these values being pushed on the stack before call.

Quote from: sinsi on June 04, 2024, 03:20:12 PMHow often do you call the generator? INT 1A returns the low tick count in DX, but the tick count is only updated 18.2 times per second. If you are too quick, you will get the same value in DX since the timer wasn't triggered.

This is the code

        invoke RNDNumber, 320
    mov lx1, ax
    invoke RNDNumber, 320
    mov lx2, ax
    invoke RNDNumber, 200
    mov ly1, ax
    invoke RNDNumber, 200
    mov ly2, ax

Quote from: daydreamer on June 04, 2024, 03:24:45 PMSimplest RNG used in infinished Perkin noise
https://masm32.com/board/index.php?topic=7324.0
Fast low quality RNG



Thanks I will check it out. This LFSR supposedly has a long period before it repeats. The only problem is maybe getting a zero output. I don't think it will be zero at any point but I will have to write a new program to test for randomness.


Tim

sinsi

AX is the wrong value to use from INT 1A, you should be using DX
INT 1Ah,  00h (0)        Read System-Timer Time Counter                   all
 
    Reports the current time of day, and whether 24 hours has passed since
    1) the last power-on, 2) the last system reset, or 3) the last system-
    timer time read or set.
 
       On entry:      AH         00h
 
       Returns:       CX         High-order part of clock count
                      DX         Low-order part of clock count
                      AL         0 if 24 hours has not passed; else 1
As you can see, AX is probably always going to be 0 (assuming the BIOS doesn't change AH).

tda0626

Quote from: sinsi on June 04, 2024, 10:42:56 PMAX is the wrong value to use from INT 1A, you should be using DX
INT 1Ah,  00h (0)        Read System-Timer Time Counter                   all
 
    Reports the current time of day, and whether 24 hours has passed since
    1) the last power-on, 2) the last system reset, or 3) the last system-
    timer time read or set.
 
       On entry:      AH         00h
 
       Returns:       CX         High-order part of clock count
                      DX         Low-order part of clock count
                      AL         0 if 24 hours has not passed; else 1
As you can see, AX is probably always going to be 0 (assuming the BIOS doesn't change AH).

I use dx but I put a copy of dx in ax to save original value of dx. Or am mixing up what you said?

Tim

sinsi

Quote from: tda0626 on June 04, 2024, 11:53:26 PMI use dx but I put a copy of dx in ax to save original value of dx. Or am mixing up what you said?
My mistake, sorry.

Quote4. Add result 2. to most significant bit after shifting seed
That's a bit ambiguous, shifting seed how many times? In which direction? I don't see an Add anywhere either.

You might want to zero DX before dividing as well.

tda0626

Quote from: sinsi on June 05, 2024, 12:26:21 AM
Quote from: tda0626 on June 04, 2024, 11:53:26 PMI use dx but I put a copy of dx in ax to save original value of dx. Or am mixing up what you said?
My mistake, sorry.

Quote4. Add result 2. to most significant bit after shifting seed
That's a bit ambiguous, shifting seed how many times? In which direction? I don't see an Add anywhere either.

You might want to zero DX before dividing as well.


No worries, sir.

I hastily wrote the explanation. You are right though it doesn't explain it concretely. It should probably say

Shift seed right by 1 then take result from step 2 and put the bit to the new shifted value's most significant bit.

Thanks for tip. Will zero out dx before div operation.

Tim

sinsi

Quote from: tda0626 on June 05, 2024, 12:57:36 AMShift seed right by 1 then take result from step 2 and put the bit to the new shifted value's most significant bit.
In that case you want or ax,cx, not xor.

tda0626

Quote from: sinsi on June 05, 2024, 01:09:18 AM
Quote from: tda0626 on June 05, 2024, 12:57:36 AMShift seed right by 1 then take result from step 2 and put the bit to the new shifted value's most significant bit.
In that case you want or ax,cx, not xor.

Oops!

daydreamer

For seed,dosbox supports rdtsc,clock cycles in edx:eax

Check out hutch random pad,64 bit
Inspired me to make two different 128 bit prng
But must have test tool for all prng coders is John walkers ENT program
It analysis entropy = quality of your prng output
Well how unique random number sequence is


my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

NoCforMe

Quote from: daydreamer on June 05, 2024, 05:13:40 AMFor seed,dosbox supports rdtsc,clock cycles in edx:eax
Um, <cough> <cough> 16-bit programming???
Assembly language programming should be fun. That's why I do it.

FORTRANS

Hi,

Quote from: NoCforMe on June 05, 2024, 06:20:02 AM
Quote from: daydreamer on June 05, 2024, 05:13:40 AMFor seed,dosbox supports rdtsc,clock cycles in edx:eax
Um, <cough> <cough> 16-bit programming???

   32-bit code works perfectly well in real mode.  Not
sure about specific instructions though.  But the general
purpose 32-bit registers can be useful with the normal
math and logical instructions.  And it can be fun to muck
about with them to see if you can write useful code.  The
32-bit addressing is normally limited to a 64k range, but
can also be used.

Cheers,

Steve N.