一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術|

服務器之家 - 編程語言 - JAVA教程 - Java中隨機數的產生方式與原理詳解

Java中隨機數的產生方式與原理詳解

2020-07-04 10:49java教程網 JAVA教程

這篇文章主要介紹了Java中隨機數的產生方式與原理詳解的相關資料,需要的朋友可以參考下

Java隨機數的產生方式與原理

查閱隨機數相關資料,特做整理

首先說一下java中產生隨機數的幾種方式

  1. 在j2se中我們可以使用Math.random()方法來產生一個隨機數,這個產生的隨機數是0-1之間的一個double,我們可以把他乘以100,他就是個100以內的隨機數字,這個在j2me中沒有。
  2. 在java.util這個包里面提供了一個Random的類,我們可以新建一個Random的對象來產生隨機數,他可以生產隨機整數、隨機float、隨機double、隨機long,這個也是我們在j2me的程序里經常用的一個取隨機數的方法。
  3. 在我們的System類中有一個currentTimeMillis()方法,這個方法返回一個從1970年1月1號0點0分0秒到目前的一個毫秒數,返回類型是long,我們可以拿他作為一個隨機數,我們可以拿他對一些數取模,就可以把他限制在一個范圍之內啦。

EN。。。其實在Random的默認構造方法里也是使用上面第三種方法進行隨機數的產生的。

對于方法二中的Random類有兩種構建方式:帶種子和不帶種子

不帶種子:此種方式將會返回隨機的數字,每次運行結果不一樣,相當于用System.currentTimeMillis()作種子。

帶種子:此種方式,無論程序運行多少次,返回結果都是一樣的。如果用相同的種子創建兩個Random實例,則對每個實例進行相同的方法調用序列,它們將生成并返回相同的數字序列。

偽隨機數

計算機中的隨機數都是偽隨機數

下面看這樣一個C程序:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// rand_1.cpp
#include <stdlib.h>
static unsigned int RAND_SEED;
unsigned int random(void)
{
  RAND_SEED = (RAND_SEED*123+59)%65536;
  return (RAND_SEED);
}
void random_start(void)
{
  int temp[2];
  movedata(0x0040,0x006c,FP_SEG(temp),FP_OFF(temp),4);
  RAND_SEED = temp[0];
}
void main()
{
  unsigned int i,n;
  random_start();
  for(i=0;i<10;i++)
     printf("#u\t",random());
  printf("\n");
}

它完整地闡述了隨機數產生的過程:

首先,

movedata(0x0040,0x006c,FP_SEG(temp),FP_OFF(temp),4);

這個函數用來移動內存數據,其中FP_SEG(far pointer to segment)是取temp數組段地址的函數,FP_OFF(far pointer to offset)是取temp數組相對地址的函數,movedata函數的作用是把位于0040:006CH存儲單元中的雙字放到數組temp的聲明的兩個存儲單元中。這樣可以通過temp數組把0040:006CH處的一個16位的數送給RAND_SEED。
其次,

RAND_SEED=(RAND_SEED*123+59)%65536;

是用來計算隨機數的方法,隨機數的計算方法在不同的計算機中是不同的,即使在相同的計算機中安裝的不同的操作系統中也是不同的。我在linux和windows下分別試過,相同的隨機種子在這兩種操作系統中生成的隨機數是不同的,這說明它們的計算方法不同。

然后,

movedata(0x0040,0x006c,FP_SEG(temp),FP_OFF(temp),4);

隨機種子為什么要在內存的0040:006CH處取?0040:006CH處存放的是什么?

學過《計算機組成原理與接口技術》這門課的人可能會記得在編制ROM BIOS時鐘中斷服務程序時會用到Intel 8253定時/計數器,它與Intel 8259中斷芯片的通信使得中斷服務程序得以運轉,主板每秒產生的18.2次中斷正是處理器根據定時/記數器值控制中斷芯片產生的。在我們計算機的主機板上都會有這樣一個定時/記數器用來計算當前系統時間,每過一個時鐘信號周期都會使記數器加一,而這個記數器的值存放在哪兒呢?沒錯,就在內存的0040:006CH處,其實這一段內存空間是這樣定義的:

TIMER_LOW DW ? ;地址為 0040:006CH
TIMER_HIGH DW ? ;地址為 0040:006EH
TIMER_OFT DB ? ;地址為 0040:0070H

時鐘中斷服務程序中,每當TIMER_LOW轉滿時,此時,記數器也會轉滿,記數器的值歸零,即TIMER_LOW處的16位二進制歸零,而TIMER_HIGH加一。rand01.c中的

movedata(0x0040,0x006c,FP_SEG(temp),FP_OFF(temp),4);

正是把TIMER_LOW和TIMER_HIGH兩個16位二進制數放進temp數組,再送往RAND_SEED,從而獲得了“隨機種子”。
現在,可以確定的一點是,隨機種子來自系統時鐘,確切地說,是來自計算機主板上的定時/計數器在內存中的記數值。

EN...沒有最后。。lvl--

再看一段代碼:

?
1
2
3
4
5
6
7
8
9
10
11
//rand_2.cpp
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
  srand((unsigned)time(NULL));
  unsigned int r=rand();
  cout<<"r = "<<r<<endl; //根據C++ 98標準,可以不用return語句來介紹main函數
  return 0;
}

這里用戶和其他程序沒有設定隨機種子,則使用系統定時/計數器的值做為隨機種子,所以,在相同的平臺環境下,編譯生成exe后,每次運行它,顯示的隨機數會是偽隨機數,即每次運行顯示的結果會有不同。

總結

隨機數是由隨機種子根據一定的計算方法計算出來的數值。所以,只要計算方法一定,隨機種子一定,那么產生的隨機數就不會變。在相同的平臺環境下,編譯生成exe后,每次運行它,顯示的隨機數都是一樣的。這是因為在相同的編譯平臺環境下,由隨機種子生成隨機數的計算方法都是一樣的,再加上隨機種子一樣,所以產生的隨機數就是一樣的。

只要用戶或第三方不設置隨機種子,那么在默認情況下隨機種子來自系統時鐘(即定時/計數器的值)

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产一级视频在线观看 | 亚洲视频久久 | 精品AV无码一二三区视频 | 天天爱天天操天天射 | 日韩香蕉网 | 99精品全国免费7观看视频 | 国产成人精品高清在线观看99 | poverty中国老妇人 | 日本免费v片一二三区 | 欧美s级人做人爱c视频 | 国产盗摄wc厕所撒尿视频 | 调教老师肉色丝袜的故事 | 亚洲国产网址 | 91久久国产成人免费观看资源 | 国产一级持黄大片99久久 | 深夜国产在线 | 第一国内永久免费福利视频 | 欧美折磨另类系列sm | 高h禁伦奶水女 | 成年人免费观看的视频 | 99视频全部看免费观 | 亚欧有色在线观看免费版高清 | 4444亚洲国产成人精品 | 国产日韩欧美在线一二三四 | 1313午夜精品理伦片 | 国内免费高清视频在线观看 | 欧美a级在线观看 | 全肉一女n男np高h乳 | 91视频免费观看网站 | 亚洲色大成网站www久久九九 | 成人午夜剧场 | 欧美一区二区三区大片 | 99精品国产成人一区二区 | 欧美性一级交视频 | 动漫精品一区二区三区3d | 向日葵视频app下载18岁以下勿看 | 粉嫩高中生第一次不戴套 | 国产精品女主播自在线拍 | 美女脱了内裤打开腿让人羞羞软件 | 国产精品主播在线 | 亚洲女人国产香蕉久久精品 |