어제 프로젝트 관련된 코딩을 하다가 난수를 써야 할 일이 있어서
C#의 Random Class에 관해 알아 보았다!
사실 Random Class의 사용방법은 그리 복잡하지도 어렵지도 않지만;
내가 만들고 싶은 난수가 적절히 만들어 지지 않아 몇시간을 테스트한김에
이와 관련된 포스팅을 하게 되었다;
예전 C언어나 C++의 rand() 함수를 사용할때는
int random = rand()%50;
위의 코드를 수행하게 되면 random 변수에는 에는 0부터 49까지 난수가 들어가게 된다;
rand()에sms seed 값이 있어 저렇게만 수행할 경우
만약 랜덤한 수가 1 3 6 2 6 순으로 나왔다면; 프로그램을 껏다 켜도 똑같은 패턴으로 나오게 된다;
그래서 아래의 항목을 추가하게 되면 그것을 막을 수 있었다;
srand(time(NULL)); // 시간에 따른 난수 발생, 없을경우 실행때마다 같은 난수가 발생한다.
이제 C# 의 Random Class를 보자;
사용법 정말 간단하다;
Random r = new Random();
생성자는 오버로딩 되어있어 생성시 시드값을 정할수 있고! 정하지 않을수 있다;
정할경우 위에 말한대로 계속 똑같은 패턴의 난수가 발생하며 디폴트일 경우에는 시스템의 시간을 이용하여
시드값을 정하기 때문에 매번 다른 패턴의 난수가 발생한다;
제공하는 매소드를 알아보자;
r.Next() : 범위가 없는 랜덤한 값을 리턴한다
r.Next(int maxValue) : 난수의 범위의 상한을 지정
r.Next(int minValue, int maxValue) : 난수의 범위의 하한과 상한을 지정!
여기서 중요한것은 난수의 하한은 난수에 포함 되지만 상한은 포함 되지 않는다는것이다;
즉 1부터 10의 값을 난수로 얻고 싶을때 Next(1,10); 을 호출하면 10은 죽어도 안나온다는 말인다;;
10을 난수로 얻고 싶다면 Next(1,11)을 호출 해야한다;
그외에
r.NextBytes()
r.NextDouble()
메소드가 있는데 int값만 필요해서 사용하지는 않았지만 메소드 명으로 쉽게 짐작 할수 있다;
이제 본론으로 들어가서 이렇게 간단한 Random Class의 사용방법을 포스팅을 하게 된 이유는
내가 발생하고 싶은 난수가 특정시간에 여러개의 객체를 생성할때 각각의 객체마다 다른
난수를 가지고 있게 하고 싶었지만 Seed값을 기본적으로 시간을 사용하기 때문에
할수가 없어서이다;
다음의 예제를 보면;
class Program { static void Main(string[] args) { for (int i = 0; i < 10; i++) { Item item = new Item(); } } } class Item { int num1; int num2; public Item() { Random r = new Random(); num1 = r.Next(1, 100); num2 = r.Next(100, 200); Console.WriteLine("{0} , {1}", num1, num2); } }
매우 간단한 구조이다 Main()에서는 Item 객체를 10개 만들고
Item 객체의 생성자에서는 난수를 2개 (각각 1~99, 100~199 범위의 값) 발생시켜
출력한다;
어떤 결과가 나올까? 10개의 객체는 각각 다른 난수를 가지고 있을까?
-- 실행 결과 --
결과처럼 '아니오' 이다;
이와 같은 발생의 이유는 기본적으로 난수발생의 시드가 시간이기 떄문이다;
위에 예제처럼 빠르게 10개의 객체를 생성할 경우 시드가 같아져 같은 결과가 나오는것이다;
어떻게 해결할까?
밑의 두가지 예제의 차이를 알게되면 쉽게 해결 가능하다;
예제1)
Random r = new Random();
for (int i = 0; i < 10; i++)
{
Console.WriteLine("{0}", r.Next());
}
예제2)
for (int i = 0; i < 10; i++)
{
Random r = new Random();
Console.WriteLine("{0}", r.Next());
}
--결과 화면--
화면에서 보다싶이 Random 객체를 빠르게 10번 생성한 예제 2에서는 같은 번호가 나왔고
객체를 재사용한 예제1에서는 다른 결과가 나왔다;
이 차이를 이용해 위에서 실패한 Item class에 랜덤한값을 배치 할수 있는것이다;
Random 객체를 static으로 두고 하나만 계속 사용한다면 위의 예제도 우리가 원하는 난수를 갖게 될것이다;
'.NET > Visual C#' 카테고리의 다른 글
Windows Form의 Loaded 이벤트 (5) | 2009.06.11 |
---|---|
트레이 아이콘을 가지는 윈도우 만들기 (17) | 2009.06.08 |
[Win32API] 타이틀바 높이 알아오기 - GetSystemMetrics() (1) | 2009.05.31 |
[Win32API] 키 이벤트 발생 시키기 - keybd_event() (3) | 2009.05.15 |
NET Framework 3.0 LINQ (6) | 2008.12.23 |