如何种子生成随机数?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何种子生成随机数?相关的知识,希望对你有一定的参考价值。
它不会产生预期的随机性。
我想从一个像66美元这样的种子开始,然后测量最后两个位,ror会给我下一个随机数,依此类推,但它只显示$ B3并且根本没有变化。
我打算怎么喂?随机上面的行显示了portc上的数字,因为我希望两个数字相继显示。
我只使用avr studio 4 for atmega 8535 at 1Mhz。
> ;Program to random numbers on port C
>
> ;Stack and Stack Pointer Addresses .equ SPH =$3E
> ;High Byte Stack Pointer Address .equ SPL =$3D
> ;Low Byte Stack Pointer Address
>
> .equ RAMEND =$25F ;Stack Address
>
> ;Port Addresses
>
> .equ PORTC =$15 ;Port C Output Address
>
> .equ DDRC =$14 ;Port C Data Direction Register
> Address
>
> .equ numberoneddr=DDRC
>
> .equ numberoneport=portc
>
> .equ numbertwoddr=DDRC
>
> .equ numbertwoport=portc
>
> .equ delayCount=21
>
> .equ random1 =$66
>
> ;Register Definitions
>
> .def numberone =r1 ;Register to store data pointed
> to by Z
>
> .def numbertwo =r2
>
> .def temp =r16 ;Temporary storage register
>
>
>
> reset:
>
> ; initialize stack pointer. Done automatically at reset on many AVRs
>
> ldi temp, low (RAMEND)
>
> out spl, temp
>
> ldi temp, high (RAMEND)
>
> out sph, temp
>
>
>
>
> ;port initialisation
>
> ldi temp,$FF
>
> out numberoneddr,temp
>
> out numberoneport,temp
>
> out numbertwoddr,temp
>
> out numbertwoport,temp
>
>
>
> ;Program Initialisation
>
> ldi temp,$66
>
> rcall random
>
> mov numberone, temp
>
> out numberoneport,numberone
>
> rcall random
>
> mov numbertwo, temp
>
> out numberoneport,numbertwo
>
>
>
>
> random: mov r19,temp
>
> ldi r17, 0x01
>
> eor r19,r17
>
> ror r19
>
> mov temp,r19
>
> ret
>
>
>
> delay:
> clr r20
>
> clr r21
>
> ldi r22, delayCount
>
> loopDelay:
>
> dec r20
>
> brne loopDelay
>
> dec r21
>
> brne loopDelay
>
> dec r22
>
> brne loopDelay
>
> ret
经过一些搜索我的古代asm源代码档案后,我发现这是我在以后使用的x86 MSDOS NASM平台:
;.rnd ;al=rnd num <0,ah>;
.rnd: pusha
mov cx,ax
.rnd0: mov bx,[cs:.rnddat]
mov ax,[cs:.rndtim]
xor al,bh
add ah,bh
rcr ax,3
xor al,bl
rcl ax,2
.rnd2: cmp al,ch
jbe .rnde
sub al,ch
or ch,ch
jnz .rnd2
sub al,al
.rnde: mov ah,bl
mov [cs:.rnddat],ax
or al,1
xor ax,[fs:046Ch]
add [cs:.rndtim],ax
popa
mov al,[cs:.rnddat]
ret
.rnddat:db 0,0
.rndtim:dw 0
想法是让一些存储的数字执行一些基本的ALU操作,如+,*,/,<<,>>,&,^
但确保不发生饱和,并且通常交换一些值的H,L
以保持随机性。所以把它移植到你的asm但我强烈建议你编写它并首先尝试在PC上查看随机性是否适合你的任务。
顺便说一下,你也可以使用程序存储器或任何ROM内容作为随机基础...这也是利用内部RTC块,所以你必须省略该部分或添加一个定时器或只是循环通过一堆非空数据。
[0000:046C] are 4 Bytes master clock count (long integer) 0 = midnight and increments until a 24 hour equiv.
我发现了我的老版本,名为NoSignal(1997年来自TASM),内部有rnd:
.386P
IDEAL
MODEL TINY
CODESEG
STARTUPCODE
main: mov ax,19 ;320*200*256
int 16
push 0A000h ;Video segment
pop es ;keyboard test,speaker delay v si=256
l0: ror ax,cl ;rnd...ax
add ax,di
stosw ;plot...
loop r1 ;speaker delay...
mov cx,si
out 61h,al
r1: or di,di
jnz l0
push ax
mov ah,1 ;test keyboard
int 16h
pop ax
jz l0
ende: sub ax,ax ;turn off speaker and exit
out 61h,al
int 16h
mov ax,3
int 16
ret
END
它为屏幕和扬声器填充白噪声,就好像模拟电视中没有天线电缆一样。这个版本长44个字节,伪随机生成器从标签l0:
开始
- qazxsw poi是生成的数字(以及之前生成的数字,就像你的temp)
ax
正在递增(类似于实际时间)......di
正在减少
所以如果我看对了它应该就够了:
cl
并根据需要添加 rnd:ror ax,cl ;rnd...ax
add ax,di
inc di
dec cl
ret
存储寄存器/值。如果你需要更复杂的东西,那就使用modulo prime算术。
[edit1]简单的C ++伪随机生成器
push/pop
上述随机生成器被加重到DOS环境时间或特殊用途。这个不是......随机性是这样的:
当我用它来填充NoSignal图像窗口时,结果如下:
这里是Gif动画:
NoSignal填充代码如下:
WORD rnd_d0=0x66; // these are seed numbers if not selected right then the randomness is not good
WORD rnd_d1=0x5A; // these give fairly good results
WORD rnd_d2=0xC3;
WORD rnd()
{
rnd_d0^=rnd_d1|rnd_d2; // xor
rnd_d1*=rnd_d2; // mul
rnd_d2+=rnd_d1; // add
rnd_d0=(rnd_d0<<8)|(rnd_d0>>8); // 8bit halves swap
return rnd_d0;
}
所以只使用来自 for (int y=0;y<ys;y++)
for (int x=0;x<xs;x++)
pyx[y][x]=0x00010101*int(rnd()>>8);
伪随机数的高8bit
,乘法只是将这个16bit
数转换为灰度颜色。
8bit
是图像大小xs,ys
是指向其线条的直接图像指针
如果没有在PC上进行适当的测试,请不要更改种子数
错误选择的种子导致完全没有随机性。如果你想安全地播种(不测试),那么使用提供的常量播种,然后调用pyx
和你的新种子数一样多。现在就把这个搞得很好,所以可能会有更好的种子,这些只是我发现的第一个产生相当好结果的种子
这些种子也很好:
rnd()
以上是关于如何种子生成随机数?的主要内容,如果未能解决你的问题,请参考以下文章