c언어 난수 생성 질문드립니다.

duse0001의 이미지

#include <stdio.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>
 
int running(int var1)
{
	if (var1 == 0)	//20%확률(이김) 일때 1리턴
		return 1;
	else
		return 0;	//80%확률(짐) 일때 0리턴
}
 
int win(int money, int var2)
{
	if (var2 == 0) //1등 3배
		return money * 3;
	else if (var2 == 1) //2등 2배
		return money * 2;
}
 
int lose(int money)
{
	return money;
}
 
int game(int var1, int var2, int* money, int betting)
{
	int res;
	//srand((unsigned)time(NULL));
	res = running(var1);
	if (res == 1)
	{
		if (var2 == 0)
		{
			*money = *money + win(betting, var2);
			printf("money : %10d \t betting: %10d Win*3\n", *money, betting);
			return 0;
		}
		if (var2 == 1)
		{
			*money = *money + win(betting, var2);
			printf("money : %10d \t betting: %10d Win*2\n", *money, betting);
			return 0;
		}
		//*money = *money + win(betting, var2);
		//printf("money : %10d \t betting: %10d Win\n", *money, betting);
		//return 0;
	}
	else if (res == 0)
	{
		*money = *money - lose(betting);
		printf("money : %10d \t betting: %10d Lose\n", *money, betting);
		return 1;
	}
//	return money;
 
}
int main(void)
{
	int i = 0, var1, var2, end;
	static int cnt = 0;
	static int cnt2 = 0;
	int money = 10000000000; int betting = 10000;
 
	srand((unsigned)time(NULL));
	//_sleep(100);
	var1 = rand() % 5;
	var2 = rand() % 2;
 
 
 
 
 
	////for (i = 0; i < 20; i++)
	////{
	////	var1 = rand() % 5;
	////	var2 = rand() % 2;
	////	printf("%d %d\n", var1, var2);
	////}rand값확인 유효값확인완료
	//
	////money=game(var1, var2, &money, betting);
	////printf("money : %4d\n", money);
	//for (i = 0; i < 20; i++)
	//{
	//	var1 = rand() % 5;
	//	var2 = rand() % 2;
	//	game(var1, var2, &money, betting);
	//	printf("money : %4d\n", money);
	//}	
	////1회게임완료
 
 
	while (1)
	{
		srand((unsigned)time(NULL));
		//_sleep(100);
		var1 = rand()% 5;
		var2 = rand()% 2;
		betting = 10000;
		end = game(var1, var2, &money, betting); cnt++;
 
		if (end == 1)	//패했을시
		{
 
			while (1)	//이길때까지 반복
			{
				srand((unsigned)time(NULL));
				//_sleep(100);
				betting *= 2;
 
				var1 = rand() % 5;
				var2 = rand() % 2;
				end = game(var1, var2, &money, betting); cnt++; cnt2++;
 
				if (end == 0)
					break;
 
				if (money < 0)
				{
					printf("bankrupt!!!\n");
					printf("count : %d, continuous cnt : %d\n", cnt, cnt2 + 1);
					return 0;
				}
				//_sleep(7);
			}
		}
 
		if (money < 0)
		{
			printf("bankrupt!!!\n");
			printf("count : %d, continuous cnt : %d\n", cnt, cnt2 + 1);
			return 0;
		}
		printf("count : %d, continuous cnt : %d\n", cnt, cnt2 + 1);
		cnt2 = 0;
	}
	return 0;
}

18연패할 확률이 0.0180144%(10만분의18) 인데 실제로 돌려보면 1000번도 못가서 파산합니다..

시드값을 time으로줘서 1초도 안되는 시간에 같은값을 같는거 같은데 time(NULL)말고 다른 값을 시드로 주는 방법이 있을까해서 여쭈어봅니다.

익명 사용자의 이미지

랜덤이란 "현재까지 알려진 수를 가지고 유추해도 그 다음에 나오게 될 수를 전혀 알 수 없는 것을 의미"합니다.
-----
설마 다음 수를 유추할 수 있을까? 하지만, 유추를 해내기도 합니다. 단순 수식으로 만들어진 랜덤인 경우 seed만 알면 금방 유추가 되겠지요.

그래서, ....

안전한(다음 수를 추측이 불가한 정도가 큰~) 랜덤을 발생하기 위해서는 다양한 하드웨어 장비를 이용하기도 합니다.

리눅스의 경우 하드웨어 말고, 소프트웨어로 2가지 디바이스(논리) 파일를 제공합니다.

/dev/random ---- 안전(안전한 값을 내보낼 만큼 준비가 되었을때(엔트로피 값이 높을 때), 리턴, 보통 처음사용시에는 리턴이 잘~ 되지만, 시간이 흘러 소진되면 점점 느려지다가 멈추기도 한다. 물론, 시간이 지나면 계속 진행된다.; 이를 리턴받는 측 입장에서는 블록킹이라고도 하고, 이를 이용한 상위 구현에 따라 랜덤 함수 호출에서 멈출 수(블록) 있음; 어떤 자바 암호화 API는 이를 사용했는데, 그래서 멈추기도 함 유의)
/dev/urandom ---- 안전하지 않음(대신 호출과 즉시 값을 리턴)
입니다.

이 파일 중 하나를 열어서, 정수/문자열이던지 취향대로 읽으면 됩니다. 예를 들어, 파일을 열고, 정수포인터로 읽기하면 된다는 얘기지요.

그리고, 계속 읽어도, 무한하게 랜덤이 나오지요.

-------------------
참고로,...

원하는 랜덤 수가 특정 통계분포에 부합되게 발생하게 하려면 아래 링크를 참조.

예를 들어, Poisson 분포 성질을 갖는 어떤 시뮬레이션을 하려면 unsigned int gsl_ran_poisson (const gsl_rng * r, double mu) 를 호출해서 하면 되겠네요.

https://www.gnu.org/software/gsl/manual/html_node/Random-Number-Distributions.html

이 외에도 랜덤은 다양한 수학,과학등의 라이브러리에서 제공되니, PRNG scientific library등으로 검색하면 좋은 결과들이 기대됩니다.

Necromancer의 이미지

time() 대신 gettimeofday() 쓰셔야 할듯. time()은 초 단위까지이고, gettimeofday()는 밀리초까지 가능합니다.

gettimeofday()로 만족스럽지 않다면 rdtsc 같은 클럭카운트 cpu 명령을 인라인 어셈블리로 집어넣는 방법도 있습니다.

Written By the Black Knight of Destruction

jick의 이미지

srand는 처음에 시작할 때 한번만 하는 거고, 그 다음엔 계속 rand만 불러야 제대로 된 난수를 만들어서 쓸 수 있습니다.

rand를 부르면서 중간에 srand를 부르면 얼핏 생각하기엔 "더 랜덤"할 것 같지만 사실 srand가 인자를 이용해 난수발생기를 초기화해 버리는 역할을 하기 때문에 덜 랜덤한 안좋은 난수가 나옵니다.

지금 코드처럼 time(NULL)을 쓰면 더 말할 것도 없구요. 이번에도 주사위가 3, 다음에도 3, 그 다음에도 3... 이렇게 나오면서 "하지만 3이란 숫자 자체는 랜덤하게 구해진 거라고!" 하는 격이죠.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.