文档库 最新最全的文档下载
当前位置:文档库 › 8位单片机产生伪随机数的算法(6502版)

8位单片机产生伪随机数的算法(6502版)

8位单片机产生伪随机数的算法(6502版)
8位单片机产生伪随机数的算法(6502版)

8位单片机产生伪随机数的算法

8位单片机很多地方需要随机数,比如游戏的洗牌,可在timer中取数,但是随机数质

量不高。随机数是一个既简单又复杂的问题,这里的例子使用了众所周知的线性叠加法,没有完美的方法产生随机数,不过线性叠加法是一个合适的方法,彻底解决8位机随机数的问题。

伪随机数函数总是返回可预知的数字,像抛骰子,如果抛足够多次,那么我们得到了一

个足够长的数字序列,

3,1,5,1,4,6,5,4,6,5,4,5,6,1,3,2,1,6,4,6,5,4,3,2,1,3,2,1,4,2,3,1,3......

如果从序列中一个接一个的取出数字,那么数字就看似随机。

问题的关键是从这序列的哪个点(数字)开始取数?这个开始的点(数字)叫做种子。

注意,如果从相同的点(种子)开始,将会得到相同的数字,这是因为我们是从固定的序

列中取数字(所以叫伪随机)。但这却是一个有用的特性,我们可以每次从不同的点取数,即改变种子!

在6502上,8位或16位随机数是最常用的,函数返回一个32位的数字,范围0~2^32。名词"线性叠加"听起来容易范晕, 其实只涉及二个内容:乘法和加法。三个步骤:

1. 为了取得新的种子(也就是从序列开始的那个点的数字),旧的种子和一个常数A相乘,

2. 所得结果然后和第二个常数c相加。

3. 新的种子是结果的低32位(记住,这个函数返回32位数字)。保留低32位很重要,用来获得下一个种子。

计算公式:

种子 = A * 种子 + C

此公式在几何图中表示一条直线,而且新种子由旧种子反复相加得来,所以叫线性叠加。

随机数函数的关键在于选择优秀的"常数A"(也叫乘数A),其实也就是选择了一个固定

的数字序列。"常数c",不像乘数A那样重要,但是它一定是个奇数。事实上, c可选1,而

且这是例程所使用的,因为它会简化计算。

注意,奇数(旧的种子)乘奇数(乘数A)是奇数,再加奇数(常数c)将会是一个偶数;偶数(旧的种子)乘奇数(乘数A),加奇数(常数c)将会是一个奇数。如此种子将会在奇数和偶数之间转变。因为种子的变化足够随机,所以新种子的值可以作为8位或16位随机数。

子程序F_RandomSeed,计算 "种子 = 乘数 * 种子+1" (记得,c=1)。有三个版本:

(1) 快速版本, 速度快,但占用Rom多。

(2) 兼顾版本,速度和占用Rom适中,空间和速度是在另外二个版本之间。

兼顾版B,使用了另一个神奇的数字66066(10进制).

(3) 最小版本,速度慢,但占用Rom小。

三个版本中使用的乘数1664525(10进制)=19660D(16进制),是从<<计算机程序的艺术,

第2册>>一书中选出,这是一个神奇的数字,经过论证和测试,这个数字对产生随机数至

关重要。想进一步研究的朋友可以阅读原著(参考资料2),书中以特别专业的数学方法讨论了随机数问题。这里只是应用了其中的两个常数1664525(10进制)和69069(10进制),这里不

作讨论,因为篇幅问题是借口,其实自己没弄懂。

;============================================================================== ; 快速版本

;============================================================================== 丰收先要选好种子,育种很重要,同样,获得随机种子是重要的一步。

种子变量设定在零页RAM可以提高速度。

程序F_RandomSeed计算 1664525*种子,需要5个字节(R_Seed0~R_Seed3,R_Temp)。

F_GeneratTables预先计算1664525*X(x=0~255),生成四个256字节的列表T3,T2,T1,T0.

T3,X = 表T3的第X字节 = 1664525 * X的第31~24位(X = 0 to 255)

T2,X = 表T2的第X字节 = 1664525 * X的第23~16位(X = 0 to 255)

T1,X = 表T1的第X字节 = 1664525 * X的第15~ 8位(X = 0 to 255)

T0,X = 表T0的第X字节 = 1664525 * X的第 7~ 0位(X = 0 to 255)

对于单片机来说使用1K RAM很夸张,也可以不用F_GeneratTables,直接把随机数表存

在ROM中。

;============================================================================== ; 伪随机数函数的线性叠加

; 计算 Seed = 1664525 * Seed + 1

;------------------------------------------------------------------------------

; 输入:

; R_Seed0 <--- 种子0

; R_Seed1 <--- 种子1

; R_Seed2 <--- 种子2

; R_Seed3 <--- 种子3

; 回返:

; 种子0 ---> R_Seed0

; 种子1 ---> R_Seed1

; 种子2 ---> R_Seed2

; 种子3 ---> R_Seed3

; 重写

; R_Temp

;------------------------------------------------------------------------------ ; 为提高速度R_Seed0,R_Seed1,R_Seed2,R_Seed3,R_Temp选零页Ram

; 每张列表从Rom地址 xx00h 处开始或在Rom中

;------------------------------------------------------------------------------ ; 空间: 程序58个字节

; 列表1024个字节

; 速度: 调用F_RandomSeed需要94个周期

;============================================================================== F_RandomSeed:

CLC ; 计算低32位:

LDX R_Seed0 ; 1664525*($100* R_Seed1+ R_Seed0)+1

LDY R_Seed1

LDA T0,X

ADC #1

STA R_Seed0

LDA T1,X

ADC T0,Y

STA R_Seed1

LDA T2,X

ADC T1,Y

STA R_Temp

LDA T3,X

ADC T2,Y

TAY ; 把字节3留在Y中

CLC ; 加低32位:

LDX R_Seed2 ; 1664525*($10000* R_Seed2)

LDA R_Temp

ADC T0,X

STA R_Seed2

TYA

ADC T1,X

CLC

LDX R_Seed3 ; 加低32位:

ADC T0,X ; 1664525*($1000000* R_Seed3)

STA R_Seed3

rts

;============================================================================== ; 产生T0,T1,T2和T3列表,使用F_GeneratTables,列表在ram中

;============================================================================== F_GeneratTables:

LDX #0 ;1664525*0=0

STX T0

STX T1

STX T2

STX T3

INX

CLC

L_GT1:

LDA T0-1,X ;把1664525加入

ADC #$0D ;字节0

STA T0,X

LDA T1-1,X

ADC #$66 ;字节1

STA T1,X

LDA T2-1,X

ADC #$19 ;字节2

STA T2,X

LDA T3-1,X

ADC #$00 ;字节3

STA T3,X

INX ;进位C=0退出

BNE L_GT1

RTS

;------------------------------------------------------------------------------ ; 生成的列表,如果不要F_GeneratTables,可以直接将此表放在Rom中

;------------------------------------------------------------------------------ ;1664525 * X的第31~24位(X = 0 to 255)

T3:

.DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01,$01,$01,$01,$01

.DB $01,$01,$01,$01,$01,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$03

.DB $03,$03,$03,$03,$03,$03,$03,$03,$03,$04,$04,$04,$04,$04,$04,$04

.DB $04,$04,$04,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$06,$06,$06

.DB $06,$06,$06,$06,$06,$06,$06,$07,$07,$07,$07,$07,$07,$07,$07,$07

.DB $07,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$09,$09,$09,$09,$09

.DB $09,$09,$09,$09,$09,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0B

.DB $0B,$0B,$0B,$0B,$0B,$0B,$0B,$0B,$0B,$0C,$0C,$0C,$0C,$0C,$0C,$0C

.DB $0C,$0C,$0C,$0C,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0E,$0E

.DB $0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F

.DB $0F,$0F,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$11,$11,$11,$11

.DB $11,$11,$11,$11,$11,$11,$12,$12,$12,$12,$12,$12,$12,$12,$12,$12

.DB $13,$13,$13,$13,$13,$13,$13,$13,$13,$13,$14,$14,$14,$14,$14,$14

.DB $14,$14,$14,$14,$15,$15,$15,$15,$15,$15,$15,$15,$15,$15,$16,$16

.DB $16,$16,$16,$16,$16,$16,$16,$16,$17,$17,$17,$17,$17,$17,$17,$17

.DB $17,$17,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$19,$19,$19,$19

;1664525 * X的第23~16位(X = 0 to 255)

T2:

.DB $00,$19,$32,$4C,$65,$7E,$98,$B1,$CB,$E4,$FD,$17,$30,$4A,$63,$7C

.DB $96,$AF,$C9,$E2,$FB,$15,$2E,$48,$61,$7A,$94,$AD,$C7,$E0,$F9,$13

.DB $2C,$46,$5F,$78,$92,$AB,$C5,$DE,$F7,$11,$2A,$44,$5D,$76,$90,$A9

.DB $C3,$DC,$F5,$0F,$28,$42,$5B,$74,$8E,$A7,$C1,$DA,$F3,$0D,$26,$40

.DB $59,$72,$8C,$A5,$BF,$D8,$F1,$0B,$24,$3E,$57,$70,$8A,$A3,$BD,$D6

.DB $EF,$09,$22,$3C,$55,$6E,$88,$A1,$BB,$D4,$ED,$07,$20,$3A,$53,$6C

.DB $86,$9F,$B9,$D2,$EB,$05,$1E,$38,$51,$6A,$84,$9D,$B7,$D0,$E9,$03

.DB $1C,$36,$4F,$68,$82,$9B,$B5,$CE,$E7,$01,$1A,$34,$4D,$66,$80,$99 .DB $B3,$CC,$E5,$FF,$18,$32,$4B,$64,$7E,$97,$B1,$CA,$E3,$FD,$16,$30 .DB $49,$62,$7C,$95,$AE,$C8,$E1,$FB,$14,$2D,$47,$60,$7A,$93,$AC,$C6 .DB $DF,$F9,$12,$2B,$45,$5E,$78,$91,$AA,$C4,$DD,$F7,$10,$29,$43,$5C .DB $76,$8F,$A8,$C2,$DB,$F5,$0E,$27,$41,$5A,$74,$8D,$A6,$C0,$D9,$F3 .DB $0C,$25,$3F,$58,$72,$8B,$A4,$BE,$D7,$F1,$0A,$23,$3D,$56,$70,$89 .DB $A2,$BC,$D5,$EF,$08,$21,$3B,$54,$6E,$87,$A0,$BA,$D3,$ED,$06,$1F .DB $39,$52,$6C,$85,$9E,$B8,$D1,$EB,$04,$1D,$37,$50,$6A,$83,$9C,$B6 .DB $CF,$E9,$02,$1B,$35,$4E,$68,$81,$9A,$B4,$CD,$E7,$00,$19,$33,$4C

;1664525 * X的第15~ 8位(X = 0 to 255)

T1:

.DB $00,$66,$CC,$32,$98,$FE,$64,$CA,$30,$96,$FC,$62,$C8,$2E,$94,$FA .DB $60,$C6,$2C,$92,$F9,$5F,$C5,$2B,$91,$F7,$5D,$C3,$29,$8F,$F5,$5B .DB $C1,$27,$8D,$F3,$59,$BF,$25,$8B,$F2,$58,$BE,$24,$8A,$F0,$56,$BC .DB $22,$88,$EE,$54,$BA,$20,$86,$EC,$52,$B8,$1E,$84,$EB,$51,$B7,$1D .DB $83,$E9,$4F,$B5,$1B,$81,$E7,$4D,$B3,$19,$7F,$E5,$4B,$B1,$17,$7E .DB $E4,$4A,$B0,$16,$7C,$E2,$48,$AE,$14,$7A,$E0,$46,$AC,$12,$78,$DE .DB $44,$AA,$10,$77,$DD,$43,$A9,$0F,$75,$DB,$41,$A7,$0D,$73,$D9,$3F .DB $A5,$0B,$71,$D7,$3D,$A3,$09,$70,$D6,$3C,$A2,$08,$6E,$D4,$3A,$A0 .DB $06,$6C,$D2,$38,$9E,$04,$6A,$D0,$36,$9C,$03,$69,$CF,$35,$9B,$01 .DB $67,$CD,$33,$99,$FF,$65,$CB,$31,$97,$FD,$63,$C9,$2F,$95,$FC,$62 .DB $C8,$2E,$94,$FA,$60,$C6,$2C,$92,$F8,$5E,$C4,$2A,$90,$F6,$5C,$C2 .DB $28,$8E,$F5,$5B,$C1,$27,$8D,$F3,$59,$BF,$25,$8B,$F1,$57,$BD,$23 .DB $89,$EF,$55,$BB,$21,$88,$EE,$54,$BA,$20,$86,$EC,$52,$B8,$1E,$84 .DB $EA,$50,$B6,$1C,$82,$E8,$4E,$B4,$1A,$81,$E7,$4D,$B3,$19,$7F,$E5 .DB $4B,$B1,$17,$7D,$E3,$49,$AF,$15,$7B,$E1,$47,$AD,$13,$7A,$E0,$46 .DB $AC,$12,$78,$DE,$44,$AA,$10,$76,$DC,$42,$A8,$0E,$74,$DA,$40,$A6

;1664525 * X的第 7~ 0位(X = 0 to 255)

T0:

.DB $00,$0D,$1A,$27,$34,$41,$4E,$5B,$68,$75,$82,$8F,$9C,$A9,$B6,$C3 .DB $D0,$DD,$EA,$F7,$04,$11,$1E,$2B,$38,$45,$52,$5F,$6C,$79,$86,$93 .DB $A0,$AD,$BA,$C7,$D4,$E1,$EE,$FB,$08,$15,$22,$2F,$3C,$49,$56,$63 .DB $70,$7D,$8A,$97,$A4,$B1,$BE,$CB,$D8,$E5,$F2,$FF,$0C,$19,$26,$33 .DB $40,$4D,$5A,$67,$74,$81,$8E,$9B,$A8,$B5,$C2,$CF,$DC,$E9,$F6,$03

.DB $10,$1D,$2A,$37,$44,$51,$5E,$6B,$78,$85,$92,$9F,$AC,$B9,$C6,$D3

.DB $E0,$ED,$FA,$07,$14,$21,$2E,$3B,$48,$55,$62,$6F,$7C,$89,$96,$A3

.DB $B0,$BD,$CA,$D7,$E4,$F1,$FE,$0B,$18,$25,$32,$3F,$4C,$59,$66,$73

.DB $80,$8D,$9A,$A7,$B4,$C1,$CE,$DB,$E8,$F5,$02,$0F,$1C,$29,$36,$43

.DB $50,$5D,$6A,$77,$84,$91,$9E,$AB,$B8,$C5,$D2,$DF,$EC,$F9,$06,$13

.DB $20,$2D,$3A,$47,$54,$61,$6E,$7B,$88,$95,$A2,$AF,$BC,$C9,$D6,$E3

.DB $F0,$FD,$0A,$17,$24,$31,$3E,$4B,$58,$65,$72,$7F,$8C,$99,$A6,$B3

.DB $C0,$CD,$DA,$E7,$F4,$01,$0E,$1B,$28,$35,$42,$4F,$5C,$69,$76,$83

.DB $90,$9D,$AA,$B7,$C4,$D1,$DE,$EB,$F8,$05,$12,$1F,$2C,$39,$46,$53

.DB $60,$6D,$7A,$87,$94,$A1,$AE,$BB,$C8,$D5,$E2,$EF,$FC,$09,$16,$23

.DB $30,$3D,$4A,$57,$64,$71,$7E,$8B,$98,$A5,$B2,$BF,$CC,$D9,$E6,$F3

;============================================================================== ; 最小版本

;==============================================================================

对于单片机来说,使用1K RAM或rom来完成一个随机数,是很浪费的,以下是最小版本,但是程序执行周期长。程序每次计算所需要的列表值。

;============================================================================== ; 线性叠加伪随机数函数

; 计算 R_Seed=1664525 * R_Seed + 1

;------------------------------------------------------------------------------ ; 输入:

; R_Seed0 <--- 种子0

; R_Seed1 <--- 种子1

; R_Seed2 <--- 种子2

; R_Seed3 <--- 种子3

; 回返:

; 种子0 ---> R_Seed0

; 种子1 ---> R_Seed1

; 种子2 ---> R_Seed2

; 种子3 ---> R_Seed3

; 重写

; R_Temp,R_Temp+1,R_Temp+2,R_Temp+3

; 注意

; R_Temp~R_Temp+3 和 L_Rand6 是高字节在前,低字节在后

;------------------------------------------------------------------------------ ; 空间: 53个字节

; 速度: 调用F_RandomSeed平均2744个周期

; 1624+70* N(N=种子数) = 1624~3864个周期

;============================================================================== F_RandomSeed:

LDA #1 ; R_Temp=1,需要给定初始值

LDX #3

L_Rand1 STA R_Temp,X

LSR

DEX

BPL L_Rand1

LDY #$20 ; 计算种子 = 种子 * L_Rand4+ R_Temp

BNE L_Rand5 ; 总是分支

L_Rand2 BCC L_Rand4 ; 如果零被移位,分支

CLC ; 把乘数加入乘积

LDX #3

L_Rand3 LDA R_Temp,X

ADC T_Rand6,X ;源码有误,已改正

STA R_Temp,X

DEX

BPL L_Rand3

L_Rand4 ROR R_Temp ; 右移结果

ROR R_Temp+1

ROR R_Temp+2

ROR R_Temp+3

L_Rand5 ROR R_Seed3 ; 右移种子

ROR R_Seed2

ROR R_Seed1

ROR R_Seed0

DEY

BPL L_Rand2

RTS

T_Rand6 .DB $00,$19,$66,$0D ;乘数(高字节在前)

;============================================================================== ; 兼顾版本乘数1664525(10进制)

;==============================================================================

兼顾版本是不用上面的循环加来做乘法,而是在必要的时候加上种子,$100* 种子, $10000* 种子,来获得数字序列,这样能够提高速度,又不增加太多代码。

分解公式表

b7 b6 b5 b4 b3 b2 b1 b0

$0D = 0 0 0 0 1 1 0 1 b ---> +种子

$66 = 0 1 1 0 0 1 1 0 b ---> *$100h

$19 = 0 0 0 1 1 0 0 1 b ---> *$10000h

$00 = 0 0 0 0 0 0 0 0 b --->

| | | | | | | |

| | | | | | | |

V V V V V V V V

左左左左左左

移移移移移移

6 5 4 3 2 1

位位位位位位

那么种子*bit0 时,种子*$10000+种子

种子*bit1 时,种子*$100,左移1位

种子*bit2 时,种子*$100+种子,左移2位

种子*bit3 时,种子*$10000+种子,左移3位

种子*bit4 时,种子*$10000,左移4位

种子*bit5 时,种子*$100,左移5位

种子*bit6 时,种子*$100,左移6位

;============================================================================== ; 伪随机数函数的线性叠加

; 计算 R_Seed=1664525 * R_Seed + 1

;------------------------------------------------------------------------------

; 输入:

; R_Seed0 <--- 种子0

; R_Seed1 <--- 种子1

; R_Seed2 <--- 种子2

; R_Seed3 <--- 种子3

; 回返:

; 种子0 ---> R_Seed0

; 种子1 ---> R_Seed1

; 种子2 ---> R_Seed2

; 种子3 ---> R_Seed3

; 重写

; R_Temp,R_Temp+1,R_Temp+2,R_Temp+3

;-------------------------------------------------------------------------------

; 空间: 106个字节

; 速度: F_RandomSeed 517个周期

;============================================================================== =

F_RandomSeed:

CLC ; 复制种子进入R_Temp

LDA R_Seed0 ; 计算种子 = 种子 *$10000+ 种子 +1

STA R_Temp

ADC #1

STA R_Seed0

LDA R_Seed1

STA R_Temp+1

ADC #0

STA R_Seed1

LDA R_Seed2

STA R_Temp+2

ADC R_Temp

STA R_Seed2

LDA R_Seed3

STA R_Temp+3

ADC R_Temp+1

STA R_Seed3

;-------------------------------------------------

;因为$0019660D 的Bit7=0,所以只需6次移位

;-------------------------------------------------

LDY #5

L_Rand1 ASL R_Temp ; 左移旧的种子

ROL R_Temp+1

ROL R_Temp+2

ROL R_Temp+3

;-------------------------------------------------

; 从 L_Rand4 列表取得 X, 4个索引值对应4种情况,数值选的巧妙!; X=$00, 种子 = 种子 +$10000* R_Temp

; X=$01, 种子 = 种子 +$100 * R_Temp

; X=$FE, 种子 = 种子 +$10000* R_Temp+ R_Temp

; X=$FF, 种子 = 种子 +$100 * R_Temp+ R_Temp

;-------------------------------------------------

LDX L_Rand4,Y

BPL L_Rand2 ; 分支如果 X=$00 或 X=$01

CLC ; 种子 = 种子 +R_Temp

LDA R_Seed0

ADC R_Temp

STA R_Seed0

LDA R_Seed1

ADC R_Temp+1

STA R_Seed1

LDA R_Seed2

ADC R_Temp+2

STA R_Seed2

LDA R_Seed3

ADC R_Temp+3

STA R_Seed3

INX ; $ FE->$00,$ FF->$01

INX

L_Rand2 CLC

BEQ L_Rand3 ; 如果 X=$00, 种子 =种子 + R_Temp*$10000

LDA R_Seed1 ; 种子 = 种子 + R_Temp*$100

ADC R_Temp

STA R_Seed1

L_Rand3 LDA R_Seed2

ADC R_Temp,X

STA R_Seed2

LDA R_Seed3

ADC R_Temp+1,X

STA R_Seed3

DEY

BPL L_Rand1

RTS

L_Rand4 .DB $01,$01,$00,$FE,$FF,$01

;============================================================================== ; 改进的兼顾版本B 选择新的乘数=69069(10进制)

;==============================================================================

兼顾版本B中, 用69069(10进制)替换1664525(10进制)作乘数,也就是说,选择了另外一个数字序列,这个乘数也是<<计算机程序的艺术,第2册>>一书中选出,经过论证和测试,

这个数字虽不及1664525做乘数好,但也是个神奇的数字,而且可以进一步减小程序时间。

;============================================================================== =

; 伪随机数函数的线性叠加

; 计算种子 = 种子 * 69069 + 1

;-------------------------------------------------------------------------------

; 输入:

; R_Seed0 <--- 种子0

; R_Seed1 <--- 种子1

; R_Seed2 <--- 种子2

; R_Seed3 <--- 种子3

; 回返:

; 种子0 ---> R_Seed0

; 种子1 ---> R_Seed1

; 种子2 ---> R_Seed2

; 种子3 ---> R_Seed3

; 重写

; R_Temp,R_Temp+1,R_Temp+2,R_Temp+3

;--------------------------------------------------------------------------------

; 空间: 173个字节

; 速度: F_RandomSeed 326个周期

;============================================================================== ==

F_RandomSeed:

LDA R_Seed0 ; R_Temp= 种子 *2

ASL

STA R_Temp

LDA R_Seed1

ROL

STA R_Temp+1

LDA R_Seed2

ROL

STA R_Temp+2

LDA R_Seed3

ROL

STA R_Temp+3

CLC ; R_Temp= R_Temp+ 种子 (= 种子 *3)

LDA R_Seed0

ADC R_Temp

STA R_Temp

LDA R_Seed1

ADC R_Temp+1

STA R_Temp+1

LDA R_Seed2

ADC R_Temp+2

STA R_Temp+2

LDA R_Seed3

ADC R_Temp+3

STA R_Temp+3

CLC ; 种子 = 种子 +$10000* 种子

LDA R_Seed2

ADC R_Seed0

TAX ; 把字节2保存在X中(利于提高速度)

LDA R_Seed3

ADC R_Seed1

TAY ; 把字节3保存在Y中

CLC ; 种子 = 种子 +$100* 种子

LDA R_Seed1

ADC R_Seed0

PHA ; 压入堆栈字节1

TXA

ADC R_Seed1

TAX

TYA

ADC R_Seed2

TAY

LDA R_Temp ; R_Temp= R_Temp*4(= 旧种子 *$0C) ASL

ROL R_Temp+1

ROL R_Temp+2

ROL R_Temp+3

ASL

ROL R_Temp+1

ROL R_Temp+2

ROL R_Temp+3

STA R_Temp

CLC ; 种子 = 种子 +R_Temp

ADC R_Seed0

STA R_Seed0

PLA ; 弹出堆栈的字节1

ADC R_Temp+1

STA R_Seed1

TXA

ADC R_Temp+2

TAX

TYA

ADC R_Temp+3

TAY

CLC

LDA R_Temp ; 种子 = 种子 + R_Temp*$100 ADC R_Seed1

STA R_Seed1

用C语言产生随机数

用c语言产生随机数 在C语言中,rand()函数可以用来产生随机数,但是这不是真真意义上的随机数,是一个伪随机数,是根据一个数,我们可以称它为种子,为基准以某个递推公式推算出来的一系数,当这系列数很大的时候,就符合正态公布,从而相当于产生了随机数,但这不是真正的随机数,当计算机正常开机后,这个种子的值是定了的,除非你破坏了系统,为了改变这个种子的值,C提供了srand()函数,它的原形是void srand( int a)。 可能大家都知道C语言中的随机函数random,可是random函数并不是ANSI C标准,所以说,random函数不能在gcc,vc等编译器下编译通过。 rand()会返回一随机数值,围在0至RAND_MAX 间。返回0至RAND_MAX之间的随机数值,RAND_MAX定义在stdlib.h,(其值至少为32767),运算的结果是一个不定的数,要看你定义的变量类型,int整形的话就是32767。在调用此函数产生随机数前,必须先利用srand()设好随机数种子,如果未设随机数种子,rand()在调用时会自动设随机数种子为1。一般用for语句来设置种子的个数。具体见下面的例子。 一如何产生不可预见的随机序列呢 利用srand((unsigned int)(time(NULL))是一种方法,因为每一次运行程序的时间是不同的。

在C语言里所提供的随机数发生器的用法:现在的C编译器都提供了一个基于ANSI标准的伪随机数发生器函数,用来生成随机数。它们就是rand()和srand()函数。这二个函数的工作过程如下:1) 首先给srand()提供一个种子,它是一个unsigned int类型,其取值围从0~65535; 2) 然后调用rand(),它会根据提供给srand()的种子值返回一个随机数(在0到32767之间) 3) 根据需要多次调用rand(),从而不间断地得到新的随机数; 4) 无论什么时候,都可以给srand()提供一个新的种子,从而进一步“随机化”rand()的输出结果。 下面是0~32767之间的随机数程序: #include #include #include //使用当前时钟做种子 void main( void ) {int i; srand( (unsigned)time( NULL ) ); //初始化随机数for( i = 0; i < 10;i++ ) //打印出10个随机数 printf( " %d\n", rand() ); } 根据上面的程序可以很容易得到0~1之间的随机数:

VHDL产生伪随机数

Library IEEE ; use IEEE.std_logic_1164.all ; use IEEE.std_logic_arith.all ; entity lfsr is generic (data_width : natural := 8 ); port ( clk : in std_logic ; reset : in std_logic ; data_out : out UNSIGNED(data_width - 1 downto 0) ); end lfsr ; architecture rtl of lfsr is signal feedback : std_logic ; signal lfsr_reg : UNSIGNED(data_width - 1 downto 0) ; begin feedback <= lfsr_reg(7) xor lfsr_reg(0) ; latch_it : process(clk,reset) begin if (reset = '1') then lfsr_reg <= (others => '0') ;

elsif (clk = '1' and clk'event) then lfsr_reg <= lfsr_reg(lfsr_reg'high - 1 downto 0) & feedback ; end if; end process ; data_out <= lfsr_reg ; end RTL ; Reference URL:https://www.wendangku.net/doc/a67125915.html,/eda/edasrc/6153.html

C语言中产生随机数的方法

C语言中产生随机数的方法 引例:产生10个[100-200]区间内的随机整数。 #include #include //rand函数的头文件 #include //时间函数的头文件 int main() { int i; //循环变量 srand((unsigned) time(NULL)); //产生随机数的起始数据(以时间为种子) for (i=0; i<10; i++) //printf("%d\n", rand()); //产生[0,0x7fff)即[0,32767)以内的随机整数 //printf("%d\n", rand()%100); //产生0-99的随机整数 printf("%d\n", rand()%(200-100+1) + 100); //产生[100,200]内的随机整数return 0; } 在C语言中产生随机数需要以下几个函数的配合使用。 (1)rand函数——产生伪随机数 原型:int rand(void) 头文件:stdlib.h 功能:产生从0到RAND_MAX之间的随机数。RAND_MAX的值通常是0x7fff(十六进制数7FFF,也就是十进制数32767)。 例: #include #include int main() { int k; k = rand(); printf("%d\n", k); return 0; } 编译运行,发现每次运行程序产生的随机数都是一样的。 计算机中产生随机数,实际是采用一个固定的数作为“种子”,在一个给定的复杂算法中计算结果,所以叫“伪随机数”。 C语言中由于采用固定的序列作为种子,所以每次执行所取的是同一个数。 为上面的例子增加一个循环结构: #include #include int main() { int k,i;

随机数生成算法的研究

随机数生成算法的研究 [日期:2006-05-23] 来源:作者:[字体:大中小] 张敬新 摘要:本文通过流程图和实际例程,较详细地阐述了随机数生成的算法和具体的程序设计,分析了其符合算法特征的特性。 关键词:随机数;算法;算法特征;程序设计 1 引言 在数据结构、算法分析与设计、科学模拟等方面都需要用到随机数。由于在数学上,整数是离散型的,实数是连续型的,而在某一具体的工程技术应用中,可能还有数据值的范围性和是否可重复性的要求。因此,我们就整数随机数和实数随机数,以及它们的数据值的范围性和是否可重复性,分别对其算法加以分析和设计。以下以Visual Basic 语言为工具,对整数随机数生成问题加以阐述,而对于实数随机数生成问题,只要稍加修改就可转化为整数随机数生成问题。 根据整数随机数范围性和是否可重复性,可分为: (1)某范围内可重复。 (2)某范围内不可重复。 (3)枚举可重复。 (4)枚举不可重复。 所谓范围,是指在两个数n1和n2之间。例如,在100和200之间这个范围,那么,只要产生的整数随机数n满足100≤n≤200,都符合要求。所谓枚举,是指有限的、已知的、若干个不连续的整数。例如,34、20、123、5、800这5个整数就是一种枚举数,也就是单独可以一个个确定下来。 2 某范围内可重复 在Visual Basic 语言中,有一个随机数函数Rnd。 语法:Rnd[(number)]。 参数number 可选,number 的值决定了Rnd 生成随机数的方式。Rnd 函数返回小于1 但大于或等于0 的值。

在调用Rnd 之前,先使用无参数的Randomize 语句初始化随机数生成器,该生成器具有一个基于系统计时器的种子。 若要生成某给定范围内的随机整数,可使用以下公式: Int((upperbound - lowerbound + 1) * Rnd + lowerbound) 这里,upperbound 是此范围的上限,而lowerbound 是范围的下限。 程序流程图: 程序例程:下面是一个生成10个10~20之间随机数的例子。 运行结果:12 10 20 20 17 17 18 14 12 20 3 某范围内不可重复

伪随机数列发生器-TsouShih

8位伪随机数列发生器 天津工业大学理学院 XXX XXXXXXX 2011年12月09日

背景 如果一个序列,一方面它是可以预先确定的,并且是可以重复地生产和复制的;一方面它又具有某种随机序列的随机特性(即统计特性),我们便称这种序列为伪随机序列。因此可以说,伪随机序列是具有某种随机特性的确定的序列。它们是由移位寄存器产生确定序列,然而他们却具有某种随机序列的随机特性。因为同样具有随机特性,无法从一个已经产生的序列的特性中判断是真随机序列还是伪随机序列,只能根据序列的产生办法来判断。伪随机序列系列具有良好的随机性和接近于白噪声的相关函数,并且有预先的可确定性和可重复性。这些特性使得伪随机序列得到了广泛的应用,特别是在CDMA系统中作为扩频码已成为CDMA技术中的关键问题。伪随机序列的特性对系统的性能有重要的影响,因此有必要了解和掌握伪随机序列的的概念和特性。 原理 伪随机数列的概念与特性 伪随机数列也称作PN码。它具有近似随机数列(噪声)的性质,它的相关函数接近白噪声的相关函数 (Δ函数 ),即有窄的高峰或宽的功率谱密度 ,使它易于从其他信号或干扰中分离出来。而又能按一定的规律(周期)产生和复制的序列。因为随机数列是只能产生而不能复制的,所以称其为“伪”随机数列。广泛应用于通信、雷达、导航等重要的技术领域。近年来 ,在自动控制、计算机、声学、光学测量、数字式跟踪和测距系统 ,以及数字网络系统的故障分析检测也得到广泛的应用。 伪随机数列具有这样的特点: (1)每个周期中,“1”码出现2n-1次,“0”码出现2n-1次,即0、1出现概率几乎相等。 (2)序列中连1的数目是n,连0的数目是n-1。 (3)分布无规律,具有与白噪声相似的伪随机特性。

各种分布的随机数生成算法

各型分布随机数的产生算法 随机序列主要用概率密度函数(PDF〃Probability Density Function)来描述。 一、均匀分布U(a,b) ?1x∈[a,b]? PDF为f(x)=?b?a?0〃其他? 生成算法:x=a+(b?a)u〃式中u为[0,1]区间均匀分布的随机数(下同)。 二、指数分布e(β) x?1?exp(?x∈[0,∞)βPDF为f(x)=?β ?0〃其他? 生成算法:x=?βln(1?u)或x=?βln(u)。由于(1?u)与u同为[0,1]均匀分布〃所以可用u 替换(1?u)。下面凡涉及到(1?u)的地方均可用u替换。 三、瑞利分布R(μ) ?xx2 exp[?x≥0?回波振幅的PDF为f(x)=?μ2 2μ2 ?0〃其他? 生成算法:x=?2μ2ln(1?u)。 四、韦布尔分布Weibull(α,β) xα??αα?1?αβxexp[?(]x∈(0,∞)βPDF为f(x)=? ?0〃其他? 生成算法:x=β[?ln(1?u)]1/α 五、高斯(正态)分布N(μ,σ2) ?1(x?μ)2 exp[?]x∈?2PDF为f(x)=?2πσ 2σ ?0〃其他? 生成算法: 1?y=?2lnu1sin(2πu2)生成标准正态分布N(0,1)〃式中u1和u2是相互独立的[0,1]区间

均匀分布的随机序列。 2?x=μ+σy产生N(μ,σ2)分布随机序列。 六、对数正态分布Ln(μ,σ2) ?1(lnx?μ)2 exp[?x>0PDF为f(x)=?2πσx 2σ2 ?0〃其他? 生成算法: 1?产生高斯随机序列y=N(μ,σ2)。 2?由于y=g(x)=lnx〃所以x=g?1(y)=exp(y)。 七、斯威林(Swerling)分布 7.1 SwerlingⅠ、Ⅱ型 7.1.1 截面积起伏 σ?1?exp[σ≥0?σ0截面积的PDF为f(σ)=?σ0〃【指数分布e(σ0)】 ?0〃其他? 生成算法:σ=?σ0ln(1?u)。 7.1.2 回波振幅起伏 ?AA2 ?exp[?2]A≥0〃式中A2=σ〃2A02=σ0。回波振幅的PDF为f(A)=?A02【瑞利分布R(A0)】2A0?0〃其他? 生成算法:A=?2A02ln(1?u)=σ0ln(1?u)。也可由A2=σ得A==?0ln(1?u) 7.2 SwerlingⅢ、Ⅳ型 7.2.1 截面积起伏 2σ?4σ]σ≥0?2exp[?σσ截面积的PDF为f(σ)=?0〃 0?0〃其他? 生成算法:σ=?式中u1和u2是相互独立的[0,1]区间均匀分布随机序列。 [ln(1?u1)+ln(1?u2)]〃2

随机数产生算法

最近做了一些Tencent及几家公司的面试题,发现有一种关于产生随机数的类型的题目。看到多有大牛们做出来,而且效率很高,也有不知道怎么做的,最近根据几个产生随机数的题目整理一下,发现所有的类似题目可以用一种万能钥匙解决。故分享,欢迎发表不同看法,欢迎吐槽。 题目一:给定能随机生成整数1到5的函数,写出能随机生成整数1到7的函数。 利用随机函数rand()函数生成一个等概率随机生成整数1到5的函数Rand5(),然后根据Rand5()生成Rand7(),代码如下: [cpp]view plaincopy 1.#include https://www.wendangku.net/doc/a67125915.html,ing namespace std; 3.int Rand5() 4.{ 5.int n =1 + rand()%5; 6.return n; 7.} 8.int Rand7() 9.{ 10.int n ,tmp1 ,tmp2; 11.do 12. { 13. tmp1 = Rand5(); 14. tmp2 = Rand5(); 15. n = (tmp1-1)*5+tmp2;//n是可以取1~25的随机的数。 16. } while (n>21);//当n>21舍去,这样n只能取1~21,对7取模就能取1~7之间的随机 数 17. 18.return 1+n%7; 19. } 20.int main() 21.{ 22.for (int i = 0 ; i < 100 ; i++) 23. { 24. cout<

真随机数产生方法

ATmega1 28单片机的真随机数发生矗时间:2009-12-16 15:39:00 来源:单片机与嵌入式系统作者:刘晓旭,曹林,董秀成西华大学 ATmega1 28单片机的真随机数发生矗时间:2009-12-16 15:39:00 来源:单片机与嵌入式系统作者:刘晓旭,曹林,董秀成西华大学 引言 随机数已广泛地应用于仿真、抽样、数值分析、计算机程序设计、决策、美学和娱乐之中。常见的随机数发生器有两种:使用数学算法的伪随机数发生器和以物理随机量作为发生源的真随机数发生器。要获取真正随机的真随机数,常使用硬件随机数发生器的方法来获取。这些真随机数都是使基于特定的真随机数发生源(如热噪声、电流噪声等),每次获取的真随机数都是不可测的,具有很好的随机性。 真随机数因其随机性强,在数据加密、信息辅助、智能决策和初始化向量方面有着广泛应用,构建一种基于硬件真随机数发生源,具有广泛的应用价值。但目前硬件真随机数发生源均较复杂,而且很少有基于单片机的真随机数发生器。本文利用RC充放电的低稳定度,根据AVR单片机的特点设计了一种性价比极高的真随机数发生器。该随机数发生器使用元件很少,稳定性高,对一些价格敏感的特殊场合,如金融、通信、娱乐设备等有较大的应用意义。 1 基本原理和方法 1.1 基本原理 串联的RC充放电电路由于受到漏电流、电阻热噪声、电阻过剩噪声、电容极化噪声等诸多不确定性因素的影响,其充放电稳定度一般只能达到10-3。利用这种RC充放电的低稳定度特性实现廉价的真随机数发生源。 Atmel公司AVR单片机ATmega 128以其速度快、功能强、性价比高等优点广泛应用于各种嵌入式计算场合。利用AVR单片机引脚配置灵活多样的特点,使用Amnega128 两个I/O口作为真随机数的电气接口。 其原理如图1所示。主要原理是利用串联RC电路的不确定性产生真随机数源,收集数据,通过AVR单片机ATmega128和主时钟电路量化RC电路的充放电时问,获得不确定的2位二进制数据,再利用程序将每4次采集的数据综合,最后产生1个8位的真随机数。

用C语言的rand()和srand()产生伪随机数的方法总结

标准库(被包含于中)提供两个帮助生成伪随机数的函数: 函数一:int rand(void); 从srand (seed)中指定的seed开始,返回一个[seed, RAND_MAX(0x7fff))间的随机整数。 函数二:void srand(unsigned seed); 参数seed是rand()的种子,用来初始化rand()的起始值。 可以认为rand()在每次被调用的时候,它会查看: 1)如果用户在此之前调用过srand(seed),给seed指定了一个值,那么它会自动调用srand(seed)一次来初始化它的起始值。 2)如果用户在此之前没有调用过srand(seed),它会自动调用srand(1)一次。 根据上面的第一点我们可以得出: 1)如果希望rand()在每次程序运行时产生的值都不一样,必须给srand(seed)中的seed一个变值,这个变值必须在每次程序运行时都不一样(比如到目前为止流逝的时间)。 2)否则,如果给seed指定的是一个定值,那么每次程序运行时rand()产生的值都会一样,虽然这个值会是[seed, RAND_MAX(0x7fff))之间的一个随机取得的值。 3)如果在调用rand()之前没有调用过srand(seed),效果将和调用了srand(1)再调用rand()一样(1也是一个定值)。 举几个例子,假设我们要取得0~6之间的随机整数(不含6本身): 例一,不指定seed: for(int i=0;i<10;i++){ ran_num=rand() % 6; cout<

C语言程序设计 伪随机数的产生

4.3.1伪随机数的产生 产生伪随机数的函数是rand(),该函数可随机生成0~RAND_MAX之间的一个整数。RAND_MAX是头文件中定义的一个符号常量。ANSI规定RAND_MAX的值不小于32767。 在编写程序时经常需要各种范围的随机数,如投骰子时需要的随机数是1~6,投一枚硬币会有正反面,需要的随机数是0~1。根据公式: n=a+rand()%b 可以得到所需范围内的随机数。其中,a为位移,是所需连续整数范围的第一个数,b是比例因子,是所需连续整数范围的宽度,则希望产生1~6之间随机数的公式为:face=1+rand()%6 【例4-3】编写一个模拟投掷硬币的程序,模拟20次,统计出正面出现的次数。 问题分析:每调用一次rand()函数会产生一个随机数,循环20次可以产生20个随机数。硬币有正反两面,用1代表正面,0代表反面,产生伪随机数的公式为rand()%2。 参考程序如下: /*程序名:4_3.c*/ /*功能:模拟投掷硬币20次,打印投掷结果并统计出正面出现的次数*/ #include #include int main() { int i,face,iCount=0; for(i=1;i<=20;i++) { face=rand()%2; printf("%5d",face); if(i%10==0)printf("\n"); if(face)iCount++; } printf("正面出现次数:%d次\n",iCount); return0; } 运行程序,结果为: 1100100000 1111111010 正面出现次数:11次 如果再次运行该程序,会发现结果与上面的相同。这怎么称得上是随机数呢?实际上,每次调用rand函数产生的一系列数似乎是随机的,但每次执行程序所产生的序列则是重复的。程序调试完成后,可以使用函数srand(),通过提供不同的种子产生不同的随机数序列。

随机数生成方法

University of Sydney School of Information Technologies Generating Random Variables Pseudo-Random Numbers Definition : A sequence of pseudo-random numbers ()i U is a deterministic sequence of numbers in []1,0 having the same relevant statistical properties as a sequence of random numbers. The most widely used method of generating pseudo-random numbers are the congruential generators: ()M X U M c aX X i i i i =+=?mod 1 for a multiplier a , shift c , and modulus M , all integers. The sequence is clearly periodic, with maximum period M . The values of a and c must be carefully chosen to maximise the period of the generator, and to ensure that the generator has good statistical properties. Some examples: M a c 259 1313 0 232 69069 1 231-1 630360016 0 232 2147001325 715136305 Reference: Ripley, Stochastic Simulation , Chapter 2

随机数生成函数C

随机数生成函数srand() rand() 2007年12月11日星期二01:42 如果srand每次输入的数值是一样的,那么每次运行产生的随机数也是一样的,srand(n) for(10) rand() 也就是说,以一个固定的数值作为种子是一个缺点。通常的做法是以这样一句代码srand((unsigned) time(NULL));来取代,这样将使得种子为一个不固定的数,这样产生的随机数就不会每次执行都一样了。 1,先看一个例子 #include #include #include using namespace std; int main( void ) { int i; /* Seed the random-number generator with current time so that * the numbers will be different every time we run. */ srand( (unsigned)time( NULL ) ); /* Display 10 numbers. */ for( i = 0; i < 10;i++ ) printf( " %6d\n", rand() ); } 2.关于time.h time.h中包含很多有趣的函数,譬如 char *ctime(long *clock) 本函数把clock所指的时间(如由函数time返回的时间)转换成下列格式的 字符串:Mon Nov 21 11:31:54 1983\n\0 #i nclude #i nclude #i nclude using namespace std; void main() {

MATLAB伪随机数发生器

MATLAB伪随机数发生器.txt生活是过出来的,不是想出来的。放得下的是曾经,放不下的是记忆。无论我在哪里,我离你都只有一转身的距离。 均匀性较好的随机数生成 zz from https://www.wendangku.net/doc/a67125915.html,/lanmuyd.asp?id=3379 随机数生成算法[1]是一类重要的算法,广泛应用于仿真技术等场合。然而,目前的伪随机数生成器(Pseudo-random number generator, PRNG)[2]存在一个重要缺陷,即样本分布与真实分布不一致,这主要发生在以下两种情况:①抽样代价过高,样本数目较少;②空间维数较高[3]。 因此,有必要寻找一类新的随机数发生器。准随机数发生器(Quasi-random number generator,QRNG)[4]能够生成稳定、低差异性的(low-discrepancy)样本,而与样本数目或空间维数无关[5]。故针对蒙特卡罗积分结果不稳定的情况,提出一种基于QRNG的蒙特卡罗积分,发现比传统方法性能有所提升。 伪随机数介绍 伪随机数是由确定的算法生成的,其分布函数与相关性均能通过统计测试。与真实随机数的差别在于,它们是由算法产生的,而不是一个真实的随机过程。一般地,伪随机数的生成方法主要有以下3种[6]: (1)直接法(Direct Method),根据分布函数的物理意义生成。缺点是仅适用于某些具有特殊分布的随机数,如二项式分布、泊松分布。 (2)逆转法(Inversion Method),假设U服从[0,1]区间上的均匀分布,令X=F-1(U),则X的累计分布函数(CDF)为F。该方法原理简单、编程方便、适用性广。 (3)接受拒绝法(Acceptance-Rejection Method):假设希望生成的随机数的概率密度函数(PDF)为f,则首先找到一个PDF为g的随机数发生器与常数c,使得f(x)≤cg(x),然后根据接收拒绝算法求解。由于算法平均运算c次才能得到一个希望生成的随机数,因此c的取值必须尽可能小。显然,该算法的缺点是较难确定g与c。 因此,伪随机数生成器(PRNG)一般采用逆转法,其基础是均匀分布,均匀分布PRNG 的优劣决定了整个随机数体系的优劣[7]。下文研究均匀分布的PRNG。 伪随机数生成器的缺点 重复做N=10000次试验,每次产生S=20与S=100个随机分布的样本,同时采用Kolmogorov- Smirnov假设检验(hypothesis test)来确定样本是否满足均匀分布。规定: ① 0假设(null hypothesis)为样本服从均匀分布;② 1假设(alternative hypothesis)为样本不服从均匀分布。 采用P值(∈[0, 1])衡量,P值越趋近于0,表示越有理由拒绝0假设,即样本不服从均匀分布;P值越趋近于1,表示越有理由接受0假设,即样本服从均匀分布。 如图1与图2所示:随着P值下降,样本也越来越不服从均匀分布。实践中希望P值越大越好。然而统计学的结论显示,P值一定服从均匀分布,与N、S大小无关,这表明由于随机性,总会出现某次抽样得到的样本不服从、甚至远离均匀分布。另外,样本大小的不同,造成检验标准的不同,直观上看S=100对应的均匀分布普遍比S=20对应的更均匀。因此,小样本情况下均匀分布PRNG的差异性尤为严重。

一维正态分布随机数序列的产生方法

一维正态分布随机数序列的产生方法 一、文献综述 1.随机数的定义及产生方法 1).随机数的定义及性质 在连续型随机变量的分布中,最简单而且最基本的分布是单位均匀分布。由该分布抽取的简单子样称,随机数序列,其中每一个体称为随机数。 单位均匀分布也称为[0,1]上的均匀分布。 由于随机数在蒙特卡罗方法中占有极其重要的位置,我们用专门的符号ξ表示。由随机数序列的定义可知,ξ1,ξ2,…是相互独立且具有相同单位均匀分布的随机数序列。也就是说,独立性、均匀性是随机数必备的两个特点。 随机数具有非常重要的性质:对于任意自然数s,由s个随机数组成的 s维空间上的点(ξn+1,ξn+2,…ξn+s)在s维空间的单位立方体Gs上 均匀分布,即对任意的ai,如下等式成立: 其中P(·)表示事件·发生的概率。反之,如果随机变量序列ξ1, ξ2…对于任意自然数s,由s个元素所组成的s维空间上的点(ξn+1,…ξn+s)在Gs上均匀分布,则它们是随机数序列。 由于随机数在蒙特卡罗方法中所处的特殊地位,它们虽然也属于由具有已知分布的总体中产生简单子样的问题,但就产生方法而言,却有着本质上的差别。 2).随机数表 为了产生随机数,可以使用随机数表。随机数表是由0,1,…,9十个数字组成,每个数字以0.1的等概率出现,数字之间相互独立。这些数字序列叫作随机数字序列。如果要得到n位有效数字的随机数,只需将表中每n 个相邻的随机数字合并在一起,且在最高位的前边加上小数点即可。例如,某随机数表的第一行数字为7634258910…,要想得到三位有效数字的随机数依次为0.763,0.425,0.891。因为随机数表需在计算机中占有很大内存, 而且也难以满足蒙特卡罗方法对随机数需要量非常大的要求,因此,该方法不适于在计算机上使用。 3).物理方法

随机数生成原理 实现方法 不同编程语言的随机数函数

1-0:Microsoft VC++产生随机数的原理: Srand ( )和Rand( )函数。它本质上是利用线性同余法,y=ax+b(mod m)。其中a,b,m都是常数。因此rand的产生决定于x,x被称为Seed。Seed需要程序中设定,一般情况下取系统时间作为种子。它产生的随机数之间的相关性很小,取值范围是0—32767(int),即双字节(16位数),若用unsigned int 双字节是65535,四字节是4294967295,一般可以满足要求。 1-1:线性同余法: 其中M是模数,A是乘数,C是增量,为初始值,当C=0时,称此算法为乘同余法;若C ≠0,则称算法为混合同余法,当C取不为零的适当数值时,有一些优点,但优点并不突出,故常取C=0。模M大小是发生器周期长短的主要标志,常见有M为素数,取A为M的原根,则周期T=M-1。例如: a=1220703125 a=32719 (程序中用此组数) a=16807 代码: void main( ) { const int n=100; double a=32719,m=1,f[n+1],g[n],seed; m=pow(2,31); cout<<"设置m值为"<>seed; f[0]=seed; for(int i=1;i<=n;i++) //线性同余法生成随机数 { f[i]=fmod((a*f[i-1]),(m-1)); g[i-1]=f[i]/(m-1); cout.setf(ios::fixed);cout.precision(6); //设置输出精度 cout<

随机数产生方法

伪随机数的产生,现在用得较多的是“线性同余法" 就是下面这个式子 R(n+1) = [R(n) * a + b] mod c 为使随机数分布尽量均匀,a、b 均为质数, c 一般取值域内的最大值(mod 是求余数) 从这个式了可以看出,每次产生的随机数都跟上一次产生的数有关系,那么,第一个数是怎么来的呢?这就是线性同余法中必须用的的”种子",也就是说,给定某个种子后,所产生的随机数序列是固定的,在计算机编程中,一般使用系统时间来初始化种子,就是前面代码中的 srand((unsigned)time(NULL)); 这一句了。因为每次运行程序的时间肯定不一样,所以产生散列肯定也不一样,从而达到“随机”的目的。 a,b,c 的取值我用的是 a=3373, b=1, c=32768 下面的两个子程序是我在我的项目(S7-200 226)中产生随机的系统编号用的,因为我的编号中只有4位数采用了随机数,所以下面的程序中用的是整型,最大范围为32767。如果需要更宽范围的随机数,可以采用双字类型,并适当修改程序,代码很简单,就是将上面那个表达式用 S7-200 的指令表示出来就行了。 这两个子程序是从 MicroWIN V4.0 中导出来的,可以将它们用文本编辑器保存为 AW L 文件后直接导入 MicroWIN。 使用时在第一个扫描周期调用 Srand 初始种子,需要随机数的地方调用 Random Random 有了个最大范围参数,可以限制生成的随机数的最大范围,比如我只需要4位随机数,所以一般这样调用 CALL Random, 10000, vw0,生成的数就在 0-9999 范围内 下面是代码: SUBROUTINE_BLOCK Srand:SBR17 TITLE=初始化随机数种子 // // 直接使用系统时钟的分秒来作为种子 VAR_OUTPUT seed:WORD; END_VAR

随机数产生原理及实现

电子信息与通信工程学院 实验报告 实验名称随机数的产生 课程名称随机信号分析 姓名顾康学号U201413323 日期6月6日地点南一楼东204 成绩教师董燕

以上为6种分布的实验结果 1.均匀分布 随机变量X~U(0,1)的一组样本值的模拟值一般采用某种数值计算方法产生随机数序列,在计算机上运算来得到,通常是利用递推公式: Xn=f(Xn-1,.....,Xn-k) 1.1 同余法 Xn+1 = λXn(mod M) Rn=Xn/M R1 R2...Rn即为(0,1)上均匀分布的随机数列。而上述方法是伪随机的,{Rn}本质上是递推公式给定的周期序列,周期T可看做logλ(M)。

解决方法是:选择模拟参数并对序列进行统计检验。 1.2选择模拟参数 1)周期长度取决于Xo,λ, M的选择 2)通过选取适当的参数可以改善随机数的性质 几组参考的取值 Xo =1 , λ=7 , M=10^10 Xo =1 , λ=5^13 , M=2 *10^10 Xo =1 , λ=5^17 , M=10^12 1.3对数列进行统计检验 对应序列能否看作X的独立同分布样本,须检验其独立性和均匀性 for i=2:1:size %同余法均匀分布 x(i)= mod ( v*x(i-1), M); y(i)=x(i)/M; end subplot(2,3,1); hist(y,100) [ahat,bhat,ACI,BCI]=unifit(y)% 以0.95的置信度估计样本的参数 首先我们的标准是U ~(0,1),而实验值,ACI表示ahat的范围[-0.0030,0], BCI表示bhat的范围[1.0000,1.0030]。同时样本的均值和方差分别为0.4932 和0.0830,结论与理论值很接近。该样本以0.95的可信度服从(0,1)均匀分布。 2.伯努利分布 2.1算法原理

均匀分布的随机数

随机数的产生 摘要 本文研究了连续型随机数列的产生,先给出了均匀分布的随机数的产生算法,在通过均匀分布的随机数变换得到其他连续型随机数的产生算法.在vc 环境下,我们给出了产生均匀分布随机数的算法,然后探讨了同余法的理论原理.通过均匀随机数产生其他分布的随机数,我们列举了几种通用算法,并讨论各个算法的优缺点,最后以正态分布为例验证高效舍选法的优势. 正文 一、 随机数与伪随机数 随机变量η的抽样序列12,,n ηηη ,…称为随机数列. 如果随机变量η是均匀分布的,则η的抽样序列12,,n ηηη ,…称为均匀随机数列;如果随机变量η是正态分布的随机变量则称其抽样序列为正态随机数列. 比如在掷一枚骰子的随机试验中出现的点数x 是一个随机变量,该随机变量就服从离散型均匀分布,x 取值为1,2,3,4,5,6,取每个数的概率相等均为1/6.如何得到x 的随机数?通过重复进行掷骰子的试验得到的一组观测结果12,,,n x x x 就是x 的随机数.要产生取值为0,1,2,…,9的离散型均匀分布的随机数,通常的操作方法是把10个完全相同的乒乓球分别标上0,1,2,…,9,然后放在一个不透明的袋中,搅拦均匀后从中摸出一球记号码1x 后放回袋中,接着仍将袋中的球搅拌均匀后从袋中再摸出一球记下号码2x 后再放回袋中,依次下去,就得到随机序列12,,,n x x x .通常称类似这种摸球的方法产生的随机数为真正的随机数.但是,当我们需要大量的随机数时,这种实际操作方法需要花费大量的时间,通常不能满足模拟试验的需要,比如教师不可能在课堂上做10000次掷硬币的试验,来观察出现正面的频率.计算机可以帮助人们在很短时间产生大量的随机数以满足模拟的需要,那么计算机产生的随机数是用类似摸球方法产生的吗?不是.计算机是用某种数学方法产生的随机数,实际上是按照一定的计算方法得到的一串数,它们具有类似随机数的性质,但是它们是依照确定算法产生的,便不可能是真正的随机数,所以称计算机产生的随机数为伪随机数.在模拟计算中通常使用伪随机数.对这些伪随机数,只要通过统计检验符合一些统计要求,如均匀性、随机性

伪随机数产生器

伪随机数产生器 ----------------------------------------------------------------------------- -- -- The following information has been generated by Exemplar Logic and -- may be freely distributed and modified. -- -- Design name : pseudorandom -- -- Purpose : This design is a pseudorandom number generator. This design -- will generate an 8-bit random number using the polynomial p(x) = x + 1. -- This system has a seed generator and will generate 2**8 - 1 unique -- vectors in pseudorandom order. These vectors are stored in a ram which -- samples the random number every 32 clock cycles. This variance of a -- priority encoded seed plus a fixed sampling frequency provides a

truely -- random number. -- -- This design used VHDL-1993 methods for coding VHDL. -- ---------------------------------------------------------------------------- Library IEEE ; use IEEE.std_logic_1164.all ; use IEEE.std_logic_arith.all ; entity divide_by_n is generic (data_width : natural := 8 ); port ( data_in : in UNSIGNED(data_width - 1 downto 0) ; load : in std_logic ; clk : in std_logic ; reset : in std_logic ; divide : out std_logic ); end divide_by_n ;

EXCEL随机数据生成方法

求教:我的电子表格中rand()函数的取值范围是-1到1,如何改回1到0 回答:有两种修改办法: 是[1-rand()]/2, 或[1+rand()]/2。 效果是一样的,都可生成0到1之间的随机数 电子表格中RAND()函数的取值范围是0到1,公式如下: =RAND() 如果取值范围是1到2,公式如下: =RAND()*(2-1)+1 RAND( ) 注解: 若要生成a 与b 之间的随机实数: =RAND()*(b-a)+a 如果要使用函数RAND 生成一随机数,并且使之不随单元格计算而改变,可以在编辑栏中输入“=RAND()”,保持编辑状态,然后按F9,将公式永久性地改为随机数。 示例 RAND() 介于0 到1 之间的一个随机数(变量) =RAND()*100 大于等于0 但小于100 的一个随机数(变量) excel产生60-70随机数公式 =RAND()*10+60 要取整可以用=int(RAND()*10+60) 我想用excel在B1单元个里创建一个50-80的随机数且这个随机数要大于A1单元个里的数值,请教大家如何编写公式! 整数:=ROUND(RAND()*(80-MAX(50,A1+1))+MAX(50,A1+1),0) 无需取整数:=RAND()*(80-MAX(50,A1))+MAX(50,A1)

要求: 1,小数保留0.1 2,1000-1100范围 3,不要出现重复 =LEFT(RAND()*100+1000,6) 至于不许重复 你可以设置数据有效性 在数据-有效性设 =countif(a:a,a1)=1 选中a列设有效性就好了 其他列耶可以 急求excel随机生成数字的公式,取值要在38.90-44.03之间,不允许重复出现,保留两位小数,不允许变藏 =round(RAND()*5+38.9,2) 公式下拉 Excel随机数 Excel具有强大的函数功能,使用Excel函数,可以轻松在Excel表格产生一系列随机数。 1、产生一个小于100的两位数的整数,输入公式=ROUNDUP(RAND()*100,0)。 RAND()这是一个随机函数,它的返回值是一个大于0且小于1的随机小数。ROUNDUP 函数是向上舍入数字,公式的意义就是将小数向上舍入到最接近的整数,再扩大100倍。 2、产生一个四位数N到M的随机数,输入公式=INT(RAND()*(M-N+1))+N。 这个公式中,INT函数是将数值向下取整为最接近的整数;因为四位数的随机数就是指从1000到9999之间的任一随机数,所以M为9999,N为1000。RAND()的值是一个大于0且小于1的随机小数,M-N+1是9000,乘以这个数就是将RAND()的值对其放大,用INT 函数取整后,再加上1000就可以得到这个范围内的随机数。[公式=INT(RAND()*(9999-1000+1))+1000] 3、Excel函数RANDBETWEEN是返回位于两个指定数之间的一个随机数。使用这一个函数来完成上面的问题就更为简单了。要使用这个函数,可能出现函数不可用,并返回错误值#NAME?。 选择"工具"菜单,单击"加载宏",在"可用加载宏"列表中,勾选"分析工具库",再单击"确定"。接下来系统将会安装并加载,可能会弹出提示需要安装源,也就是office安装盘。放入光盘,点击"确定",完成安装。 现在可以在单元格输入公式=RANDBETWEEN(1000,9999)。 最后,你可以将公式复制到所有需要产生随机数的单元格,每一次打开工作表,数据都会自动随机更新。在打开的工作表,也可以执行功能键F9,每按下一次,数据就会自动随机更新了。

相关文档
相关文档 最新文档