Top 22 난수 발생 The 196 Correct Answer

You are looking for information, articles, knowledge about the topic nail salons open on sunday near me 난수 발생 on Google, you do not find the information you need! Here are the best content compiled and compiled by the https://toplist.maxfit.vn team, along with other related topics such as: 난수 발생 c언어 난수 생성, 난수발생기 엑셀, 난수 생성 원리, 난수생성 알고리즘, 난수 생성 사이트, 난수생성 프로그램, 난수란, 랜덤 숫자 생성


컴퓨터가 만드는 랜덤숫자의 진실(feat.의사 난수) – [高지식] 거니
컴퓨터가 만드는 랜덤숫자의 진실(feat.의사 난수) – [高지식] 거니


난수 발생기; 랜덤 정수 생성, 무작위 숫자 발생; Random Int Number Generator

  • Article author: mwultong.blogspot.com
  • Reviews from users: 48767 ⭐ Ratings
  • Top rated: 4.7 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about 난수 발생기; 랜덤 정수 생성, 무작위 숫자 발생; Random Int Number Generator 지정한 범위의 정수로 된 무작위의 랜덤한 숫자들을 만드는 발생기입니다. 기본값은 1에서 100까지의 난수를 20개 생성하는 것인데, 마음대로 변경할 … …
  • Most searched keywords: Whether you are looking for 난수 발생기; 랜덤 정수 생성, 무작위 숫자 발생; Random Int Number Generator 지정한 범위의 정수로 된 무작위의 랜덤한 숫자들을 만드는 발생기입니다. 기본값은 1에서 100까지의 난수를 20개 생성하는 것인데, 마음대로 변경할 …
  • Table of Contents:
난수 발생기; 랜덤 정수 생성, 무작위 숫자 발생; Random Int Number Generator
난수 발생기; 랜덤 정수 생성, 무작위 숫자 발생; Random Int Number Generator

Read More

난수 발생 함수 – rand : 네이버 블로그

  • Article author: m.blog.naver.com
  • Reviews from users: 31279 ⭐ Ratings
  • Top rated: 3.7 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about 난수 발생 함수 – rand : 네이버 블로그 이때 임의로 선택한 값을 난수라고 하며 선택하는 방법은 수학적인 개념(공식)을 사용하여 직접 구현하면 됩니다. 2. rand 함수 난수를 생성하는 공식을 … …
  • Most searched keywords: Whether you are looking for 난수 발생 함수 – rand : 네이버 블로그 이때 임의로 선택한 값을 난수라고 하며 선택하는 방법은 수학적인 개념(공식)을 사용하여 직접 구현하면 됩니다. 2. rand 함수 난수를 생성하는 공식을 …
  • Table of Contents:

카테고리 이동

프로그래머 김성엽

이 블로그 
일반 강좌
 카테고리 글

카테고리

이 블로그 
일반 강좌
 카테고리 글

난수 발생 함수 - rand : 네이버 블로그
난수 발생 함수 – rand : 네이버 블로그

Read More

난수발생기 – 위키백과, 우리 모두의 백과사전

  • Article author: ko.wikipedia.org
  • Reviews from users: 45839 ⭐ Ratings
  • Top rated: 3.3 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about 난수발생기 – 위키백과, 우리 모두의 백과사전 난수발생기(亂數發生機, 영어: random number generator, RNG) 또는 난수생성기(亂數生成機)는 무작위성 기회보다 이론적으로 예측을 더 할 수 없도록 일련의 숫자나 … …
  • Most searched keywords: Whether you are looking for 난수발생기 – 위키백과, 우리 모두의 백과사전 난수발생기(亂數發生機, 영어: random number generator, RNG) 또는 난수생성기(亂數生成機)는 무작위성 기회보다 이론적으로 예측을 더 할 수 없도록 일련의 숫자나 …
  • Table of Contents:

같이 보기[편집]

외부 링크[편집]

난수발생기 - 위키백과, 우리 모두의 백과사전
난수발생기 – 위키백과, 우리 모두의 백과사전

Read More

C 랜덤 – 난수 생성하기

  • Article author: yeolco.tistory.com
  • Reviews from users: 29920 ⭐ Ratings
  • Top rated: 3.6 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about C 랜덤 – 난수 생성하기 해석하면 rand() 함수에 의해 난수를 생성하고 그 숫자를 9로 나눈 나머지를 random 변수에 대입하는 코드입니다. ※ 알고가기. …
  • Most searched keywords: Whether you are looking for C 랜덤 – 난수 생성하기 해석하면 rand() 함수에 의해 난수를 생성하고 그 숫자를 9로 나눈 나머지를 random 변수에 대입하는 코드입니다. ※ 알고가기. C언어 프로그래밍에서 코드를 작성하다보면 무작위의 숫자가 필요한 경우가 존재합니다. 보통 무작위 숫자를 난수라고 표현합니다. C언어에서 난수를 표현하기 위해서는 라이브러리를 사용해야합니다. ※ 알고가기..프로그래머의 일상 및 개발 일지
  • Table of Contents:

C 랜덤 – 난수 생성하기

티스토리툴바

C 랜덤 - 난수 생성하기
C 랜덤 – 난수 생성하기

Read More

3.5 난수 발생과 카운팅 — 데이터 사이언스 스쿨

  • Article author: datascienceschool.net
  • Reviews from users: 37514 ⭐ Ratings
  • Top rated: 3.6 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about 3.5 난수 발생과 카운팅 — 데이터 사이언스 스쿨 이렇게 시드를 설정한 후 넘파이 random 서브패키지에 있는 rand 함수로 5개의 난수를 생성해 보자. rand 함수는 0과 1사이의 난수를 발생시키는 함수로 인수로 받은 … …
  • Most searched keywords: Whether you are looking for 3.5 난수 발생과 카운팅 — 데이터 사이언스 스쿨 이렇게 시드를 설정한 후 넘파이 random 서브패키지에 있는 rand 함수로 5개의 난수를 생성해 보자. rand 함수는 0과 1사이의 난수를 발생시키는 함수로 인수로 받은 …
  • Table of Contents:

시드 설정하기¶

데이터의 순서 바꾸기¶

데이터 샘플링¶

난수 생성¶

정수 데이터 카운팅¶

3.5 난수 발생과 카운팅 — 데이터 사이언스 스쿨
3.5 난수 발생과 카운팅 — 데이터 사이언스 스쿨

Read More

컴퓨터가 만드는 랜덤은 정말로 랜덤할까? | Evans Library

  • Article author: evan-moon.github.io
  • Reviews from users: 43955 ⭐ Ratings
  • Top rated: 3.2 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about 컴퓨터가 만드는 랜덤은 정말로 랜덤할까? | Evans Library 위에서 설명했듯이 무작위 로 발생하는 어떠한 패턴이다. 사람마다 의견이 분분하겠지만 지금 필자 머리 속에 떠오른 대표적인 랜덤은 바로 도박 이다. …
  • Most searched keywords: Whether you are looking for 컴퓨터가 만드는 랜덤은 정말로 랜덤할까? | Evans Library 위에서 설명했듯이 무작위 로 발생하는 어떠한 패턴이다. 사람마다 의견이 분분하겠지만 지금 필자 머리 속에 떠오른 대표적인 랜덤은 바로 도박 이다. 이번 포스팅에서는 에 대해서 한번 이야기 해볼까 한다. 랜덤이란 어떤 사건이 발생했을 때 이전 사건과 다음 사건의 규칙성이 보이지 않는, 말 그대로 로 발생하는 패턴을 이야기한다. 우리가 사용하고 있는 컴퓨터도 랜덤한 패턴을 만들어야 할 때가 있고 또 실제로도 만들고 있다.
  • Table of Contents:

랜덤(Random)이란 무엇일까

컴퓨터에서의 랜덤

마치며

컴퓨터가 만드는 랜덤은 정말로 랜덤할까? | Evans Library
컴퓨터가 만드는 랜덤은 정말로 랜덤할까? | Evans Library

Read More

[Javascript] 난수 생성하기 (랜덤 숫자, Random Number) – 어제 오늘 내일

  • Article author: hianna.tistory.com
  • Reviews from users: 40901 ⭐ Ratings
  • Top rated: 4.1 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about [Javascript] 난수 생성하기 (랜덤 숫자, Random Number) – 어제 오늘 내일 Javascript로 난수를 생성하는 방법을 소개합니다. Math.random() 범위를 지정한 난수 생성하기 0~9 0~10 0~99 0~100 1~10 2~5 난수 생성 함수 만들기 … …
  • Most searched keywords: Whether you are looking for [Javascript] 난수 생성하기 (랜덤 숫자, Random Number) – 어제 오늘 내일 Javascript로 난수를 생성하는 방법을 소개합니다. Math.random() 범위를 지정한 난수 생성하기 0~9 0~10 0~99 0~100 1~10 2~5 난수 생성 함수 만들기 … Javascript로 난수를 생성하는 방법을 소개합니다. Math.random() 범위를 지정한 난수 생성하기 0~9 0~10 0~99 0~100 1~10 2~5 난수 생성 함수 만들기 (범위 지정) min <= number <= max ( max 값 포함) min <= nu..
  • Table of Contents:

어제 오늘 내일

[Javascript] 난수 생성하기 (랜덤 숫자 Random Number) 본문

1 Mathrandom()

2 범위를 지정한 난수 생성하기

3 난수 생성 함수 만들기 (범위 지정)

[Javascript] 난수 생성하기 (랜덤 숫자, Random Number) - 어제 오늘 내일
[Javascript] 난수 생성하기 (랜덤 숫자, Random Number) – 어제 오늘 내일

Read More

난수 발생 – Apple 지원 (KR)

  • Article author: support.apple.com
  • Reviews from users: 6128 ⭐ Ratings
  • Top rated: 4.5 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about 난수 발생 – Apple 지원 (KR) 난수 발생. CPRNG(의사 난수 발생기)는 보안 소프트웨어의 중요한 구성 요소입니다. 이를 위해 Apple은 iOS, iPadOS, macOS, tvOS 및 watchOS 커널에서 실행되는 신뢰 … …
  • Most searched keywords: Whether you are looking for 난수 발생 – Apple 지원 (KR) 난수 발생. CPRNG(의사 난수 발생기)는 보안 소프트웨어의 중요한 구성 요소입니다. 이를 위해 Apple은 iOS, iPadOS, macOS, tvOS 및 watchOS 커널에서 실행되는 신뢰 … Apple은 iOS, iPadOS, macOS, tvOS 및 watchOS의 커널에서 실행되는 신뢰하는 CPRNG(의사 난수 발생기)로 기기 보안을 달성합니다.
  • Table of Contents:

Apple 플랫폼 보안

엔트로피 소스

커널 CPRNG

Apple Footer

난수 발생 - Apple 지원 (KR)
난수 발생 – Apple 지원 (KR)

Read More

KR20040027361A – 난수 발생방법 및 난수 발생장치
– Google Patents

  • Article author: patents.google.com
  • Reviews from users: 30372 ⭐ Ratings
  • Top rated: 3.9 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about KR20040027361A – 난수 발생방법 및 난수 발생장치
    – Google Patents 쌍안정성(雙安定性) 멀티 바이브레이터 회로에 대해서 소정의 구동전압을 “입력”측으로부터 인가하여 구동시킨다. 이 때, 트랜지스터의 온/오프 상태는 상기 쌍안정성 … …
  • Most searched keywords: Whether you are looking for KR20040027361A – 난수 발생방법 및 난수 발생장치
    – Google Patents 쌍안정성(雙安定性) 멀티 바이브레이터 회로에 대해서 소정의 구동전압을 “입력”측으로부터 인가하여 구동시킨다. 이 때, 트랜지스터의 온/오프 상태는 상기 쌍안정성 …
    쌍안정성(雙安定性) 멀티 바이브레이터 회로에 대해서 소정의 구동전압을 “입력”측으로부터 인가하여 구동시킨다. 이 때, 트랜지스터의 온/오프 상태는 상기 쌍안정성 멀티 바이브레이터 회로 내의 잡음에 의존하여 무작위로 발생하도록 되어 있기 때문에 상기 트랜지스터의 도통상태(온 상태) 및 차단상태(오프 상태)에 대응시켜 숫자 “0” 및 “1”을 각각 대응시킴으로써 2진수 적인 난수를 발생시킨다.

  • Table of Contents:

Info

Links

Classifications

Abstract

Description

Claims (9)

Priority Applications (2)

Publications (1)

ID=32063520

Family Applications (1)

Country Status (6)

Families Citing this family (5)

Family Cites Families (7)

Also Published As

Similar Documents

Legal Events

KR20040027361A - 난수 발생방법 및 난수 발생장치 
        - Google Patents
KR20040027361A – 난수 발생방법 및 난수 발생장치
– Google Patents

Read More


See more articles in the same category here: 533+ tips for you.

난수 발생 함수 – rand

실행 결과 :

11451, 11451, 11451, 11451, 11451, 11451, 11451, 11451, 11451, 11451, 11451, 11451, 11451, 11451, 11451, 11451, 11451, 11451, 11451, 11451,

따라서 srand는 rand 함수가 반복적으로 사용되더라도 발생을 시작하는 시점에 한 번만 호출하는 것이 좋습니다. 그리고 srand 함수가 적용되는 단위가 스레드(thread)이기 때문에 멀티 스레드를 사용하는 프로그램이라면 스레드마다 srand를 개별적으로 사용하는 것이 좋습니다.

4. rand 함수의 활용

rand 함수를 사용하다 보면 의문이 생길 수 있습니다. 자신은 0에서 10사이의 숫자를 난수로 사용하고 싶은데 rand 함수가 발생하는 값이 0에서 32767사이의 값이기 때문에 난수의 범위가 맞지 않다는 점입니다. 하지만 이런 의문은 간단한 수학 연산으로 해결할 수 있습니다.

아래와 같이 % 연산자를 사용하여 난수 값을 11로 나눈 나머지를 사용하게 되면 rand 함수가 어떤 값을 발생시키든지 number에는 0에서 10사이의 숫자만 대입됩니다.

난수 생성하기

C언어 프로그래밍에서 코드를 작성하다보면 무작위의 숫자가 필요한 경우가 존재합니다.

보통 무작위 숫자를 난수라고 표현합니다.

C언어에서 난수를 표현하기 위해서는 라이브러리를 사용해야합니다.

※ 알고가기

라이브러리란 자주 사용하는 함수들을 미리 작성하여 저장해둔 파일로써 보통 헤더파일로 저장됩니다. 이 헤더파일은 #include 라는 코드를 통해 추가해 줄 수 있는데 C언어에서 기본적으로 사용하는 헤더파일은 stdio.h 이며 이는 Standard Input Ouput(표준 입출력)의 약자입니다. 사용방법은 프로그램 코드 맨 윗줄에 #include <헤더파일명.h> 또는 “헤더파일명.h” 으로 사용할 수 있습니다. 보통 < > 는 Standard Library Header에서 사용하며 ” “는 User Defined Header를 사용할 때 쓰는것이라 알려져있는데 크게 틀린말은 아닙니다. < >와 ” “의 차이는 – < > : 컴파일러가 미리 정해놓은 위치에서 헤더파일을 찾습니다. – ” ” : 컴파일러가 미리 정해놓은 위치에서 헤더파일을 찾고 만약 찾지 못한다면, < >로 바꾸어 헤더파일을 찾습니다. 로 생각하면 되겠습니다. 결국 Header파일을 읽은 것인지 Source파일을 읽을 것인지에 따라 사용을 구분하면 되겠습니다.

다시 본론으로 와서, C언어에서 난수를 만들기위해서는 rand()라는 함수를 사용하면 됩니다.

rand()함수는 stdlib.h 헤더파일에 포함되어있기 때문에 코드 맨 윗줄에 #include 를 작성해 줍니다.

☞ rand()함수 사용법

#include #include // rand() 함수 포함 라이브러리

int main() { int random = 0; // 정수형 변수 선언 for (int i = 0; i < 10; i++) { // 10번 반복 random = rand()%9; // 난수 생성 printf("%d ", random); // 출력 } } ☞ 실행결과 8번째 줄을 보시면 random = rand()%9; 라는 코드가 있습니다. 해석하면 rand() 함수에 의해 난수를 생성하고 그 숫자를 9로 나눈 나머지를 random 변수에 대입하는 코드입니다. ※ 알고가기 rand() 함수에 의해 생성되는 난수 : 0 ~ 32767 rand() 함수에 의해 생성된 난수를 9로 나눈 나머지(%)의 값은 0부터 8까지입니다. 이를 1부터 9까지 난수를 생성하고 싶을때는 다음과 같이 8번째 줄 코드를 변경합니다. random = rand()%9 + 1; 이는 0부터 8까지 반환되는 난수에 1을 더해줌으로써 1부터 9까지 반환할 수 있도록 하는 코드입니다. 하지만 여기서 문제점이 발생합니다. 분명 개발자가 원하는 난수를 생성하고 출력했지만 그 패턴(규칙)이 매번 일정하다는 겁니다. 다시말해, 프로그램 실행 시(또는 반복문) 항상 같은 난수가 생성된다는 겁니다. 이는 진정한 난수라고 말할 수 없죠. 그렇다면 프로그램 실행 시 매번 다르게 난수를 생성하는 방법은 무엇일까요? 그건 바로 srand()라는 함수를 사용하면 됩니다! rand() 함수를 사용하기 전에 다음과 같은 코드를 추가합니다. srand(time(NULL)); 무슨뜻이냐면 srand()함수는 rand()라는 함수에 무작위의 시드값을 주기위한 함수이며 그 파라미터로 time(NULL)이라는 매개변수를 전달합니다. time(NULL)은 1970년 1월 1일 이후 경과된 시간을 초 단위로 반환하는 함수입니다. 이로써 1초 단위로 매번 다른 시드값을 생성해 rand()함수를 호출하는 것입니다. 이해가 안가시는분은 그냥 이걸 써야 진정한 난수가 생성되는구나! 라고 생각하시면 됩니다. 물론 time()함수를 사용하기 위해서 #include 를 추가해주시는걸 잊지마세요!

☞ 진정한 난수 생성코드

#include #include // rand()함수 포함 라이브러리 #include // time()함수 포함 라이브러리

int main() { srand(time(NULL)); // 매번 다른 시드값 생성 int random = 0; // 정수형 변수 선언 for (int i = 0; i < 10; i++) { // 10번 반복 random = rand()%9; // 난수 생성 printf("%d ", random); // 출력 } } ☞ 실행결과 3번 실행 한 결과 모두 다른 난수값이 생성되는것을 확인 할 수 있습니다! 이로써 진정한 난수 생성하는 방법 및 코드에 대해 알아보았습니다. 정보가 유익하셨다면 아래 공감버튼 눌러주시면 감사하겠습니다. 질문사항은 댓글로 달아주시면 성의껏 답변해드리겠습니다.

컴퓨터가 만드는 랜덤은 정말로 랜덤할까?

이번 포스팅에서는 랜덤 에 대해서 한번 이야기 해볼까 한다. 랜덤이란 어떤 사건이 발생했을 때 이전 사건과 다음 사건의 규칙성이 보이지 않는, 말 그대로 무작위 로 발생하는 패턴을 이야기한다. 우리가 사용하고 있는 컴퓨터도 랜덤한 패턴을 만들어야 할 때가 있고 또 실제로도 만들고 있다.

하지만 컴퓨터는 사실 그냥 기능이 많은 계산기 에 불과하다. 계산기는 입력된 값을 가지고 이리 저리 가지고 놀다가 결과값을 내놓는 물건이다. 근데 이런 계산기가 어떻게 랜덤 한 결과를 만들어낼 수 있는 것일까? 우리는 이 질문에 대한 답을 찾기 전에 근본적으로 랜덤이란 것이 무엇인지부터 생각해봐야한다. 진짜 무작위 라는 것이 존재하기는 하는 걸까?

먼저, 랜덤 이란 무엇일까? 위에서 설명했듯이 무작위 로 발생하는 어떠한 패턴이다.

사람마다 의견이 분분하겠지만 지금 필자 머리 속에 떠오른 대표적인 랜덤은 바로 도박 이다. 도박의 가장 위험한 점이 비록 이번 판에는 잃었지만 다음 판에는 나도 딸 수 있을거야! 라는 희망인데, 이런 희망은 도박할 때 사용하는 게임들이 랜덤 에서 기반하는 게임이라는 생각에서 출발하기 때문이다. 즉, 어느 정도 운빨게임이어야 한다는 것이다.

대법원 판례 2006도736에도 도박의 정의를 재물을 걸고 우연에 의하여 재물의 득실을 결정하는 것 이라고 이야기하고 있다. 대표적인 도박인 파칭코, 섰다, 포커, 주식 등만 살펴봐도 대충 감이 온다.

필자는 도박에서 사용하는 게임을 잘 모르기 때문에 누구나 해봤을 법한 가벼운 도박을 예로 들어보겠다. 필자가 중고등학생 시절을 보낸 2000년대에 전국의 중, 고등학교에서 널리 행해졌던 놀이인 판치기 이다. 판치기는 워낙 전국적으로 유행했기 때문에 필자 또래의 독자분들이면 독자분들이면 한번 쯤은 해봤거나 아니면 친구들이 하는 걸 보기는 했을 거라 믿는다.

판치기하다가 선생님들한테 걸리면 교무실로 끌려가서 바로 빠따행이었다.

그래도 혹시 판치기가 뭔지 모르는 분들이 있을 수 있으니 일단 간단하게 룰을 설명하겠다.

적당히 두꺼운 교과서를 준비한다. 국사책이나 물리책처럼 적당히 두꺼운 책을 사용하자. 각자 준비한 동전을 교과서에 올린다. 보통 100원을 건다. 순서대로 교과서를 손으로 때려서 동전을 뒤집는다. 모든 동전을 뒤집어서 같은 면으로 만든 사람이 판돈을 모두 가져간다.

상식적으로 교과서를 손으로 때렸을 때 n 개의 동전이 뒤집어 질 것이라는 계산을 하기란 쉽지 않다. 즉, 판치기는 어느 정도 랜덤 에 기반한 게임이고 그래서 도박 의 기본적인 특성인 사행성 을 가질 수 있는 것이다.

참고로 형법 제 246조 1항과 국내 도박법 판례 상 학교에서 하는 판돈이 몇백원 정도인 판치기는 일시 오락으로 판정받아서 무죄이지만, 아무리 판치기라고 해도 몇백만원 수준의 돈이 왔다갔다 하는 수준이면 도박죄로 처벌받을 수 있다는 점 알아두자. (물론 저 정도 돈이 있는 사람들이면 판치기말고 다른 걸 한다…)

그럼 이 쯤에서 처음의 그 질문을 한번 던져보겠다.

이게 정말로 랜덤일까?

예전에 필자의 학창시절을 생각해봐도 학교에 1~2명씩 판치기의 절대 고수들이 있었는데 이 친구들은 자신이 원하는 동전만 정확히 뒤집을 수 있는 능력을 보유하고 있었다. 예전에 TV에서도 판치기의 고수라고 나온 분이 있었는데 이 분은 뭐 거의 닥터 스트레인지 수준이었다.

사실 판치기도 결국은 물리 법칙 내에서 돌아가는 판이기 때문에 판돈으로 걸린 동전의 무게, 판을 내려치는 힘, 판으로 사용된 교과서의 탄력성 등 몇가지 변수를 알면 어느 동전이 뒤집어 질지도 계산할 수 있을 것이다. 물론 이렇게 계산하는 것이 쉬운 일은 아니기 때문에 우리는 진정한 의미의 랜덤 이 아니더라도 이 정도면 그냥 랜덤 하다고 치는 것이다.

즉, 우리 주변에서도 진정한 의미의 랜덤은 그렇게 많지 않다는 것을 알 수 있다. 단지 우리가 랜덤하다고 생각할 뿐이다.

컴퓨터에서의 랜덤

사실 우리가 일상에서 어느 정도 우연성이 있다면 랜덤하다고 하듯이 컴퓨터도 진정한 의미의 랜덤을 만들어 내는 것이 아니라 어느 정도 납득할만한 우연성을 만들어 내고 이를 랜덤하다고 한다. 게다가 컴퓨터로 뭔가를 만드려면 어떠한 규칙을 만들어줘야 하는데, 어떠한 규칙으로 규칙이 없는 랜덤을 생성한다는 말 자체가 모순이다.

그래서 우리는 랜덤은 아니지만 랜덤에 가까운 유사 랜덤(Pseudo Random) 밖에 만들 수 밖에 없는 것이다. 또한 컴퓨터는 기본적으로 숫자를 기반으로 하는 일종의 계산기이기 때문에 랜덤한 사건을 만들기 위해서는 난수 , 즉 랜덤한 수를 뽑아 낼 수 있어야 한다.

그럼 컴퓨터는 어떻게 이런 난수 생성을 하는 걸까?

중앙제곱법(Mid Square Method)

중앙제곱법 은 폰 노이만이 1949년에 고안한 유사 난수 생성법으로, 임의의 숫자를 제곱한 다음 이 숫자의 일부분을 가져와서 새로운 난수로 만들어내는 방법이다.

임의의 4자리 난수를 만든다고 가정해보자. 초기 값은 심플하게 1234 로 가겠다.

페이즈 대상값 제곱값 난수 0 1234 1522756 1522756 1 5227 27321529 27321529 2 3215 10336225 10336225

이런 식으로 계속 중앙에 있는 값을 빼와서 제곱하면서 임의의 난수를 생성하는 방법이 바로 중앙제곱법 이다. 뭔가 딱봐도 예측하기 쉬워보인다. 아무래도 폰 노이만 형이 활동하던 1950년대에 개발된 알고리즘이고, 그 당시 컴퓨터의 성능은 눈물나기 그지 없었으므로 최대한 간단한 방법을 사용한 것이다. 그래서 이 방법은 요즘에는 거의 사용되지 않는다.

선형합동법(Linear Congruential Method)

선형합동법 은 C의 rand 함수에서 사용하는 알고리즘이며 다음과 같은 재귀 관계식으로 정의되며 난수들의 수열을 반환한다.

X n + 1 = ( a X n + c ) m o d m X_{n+1} = (aX_n + c) \mod m X n + 1 ​ = ( a X n ​ + c ) m o d m

여기서 X X X는 난수로 된 수열이고 나머지는 그냥 임의의 정수이다. 참고로 ANSI C 표준은 m = 2 31 , a = 1103515245 , c = 12345 m = 2^{31}, a = 1103515245, c = 12345 m=231,a=1103515245,c=12345로 정해져있다. 그럼 간단하게 한번 자바스크립트를 사용해서 구현해보자.

let m = 2 ** 31 ; const a = 1103515245 ; const c = 12345 ; function rand ( x ) { return ( ( ( x * a ) + c ) % m ) ; } function getRandomNumbers ( randCount = 1 ) { const initial = new Date ( ) . getTime ( ) ; const randomNumbers = [ initial ] ; for ( let i = 0 ; i < randCount ; i ++ ) { randomNumbers . push ( rand ( randomNumbers [ i ] ) ) ; } randomNumbers . shift ( ) ; return randomNumbers ; } console . log ( getRandomNumbers ( 10 ) ) ; 코드를 브라우저 콘솔에 붙혀넣고 실행시켜보면 인자로 주었던 10만큼의 길이를 가진 난수 배열이 출력된다. ( 10 ) [ 1163074432 , 465823232 , 1719475776 , 1744670976 , 790949120 , 552540416 , 896259328 , 1473241344 , 1074855168 , 575793408 ] 선형합동법 의 특징은 이전에 생성된 난수를 활용한다는 것이며 최대 m m m만큼 경우의 수를 가지므로 최악의 경우 m m m 만큼의 반복 주기를 가진다. 필자가 m 변수를 let 키워드로 선언한 건 이 이유다. 한번 브라우저에서 m 변수에 작은 수를 할당한 다음에 getRandomNumbers 함수를 다시 호출해보자. 난수의 경우의 수와 동일한 값이 출현이 눈에 띄게 커진다는 것을 확인해볼 수 있다. 선형합동법은 계산이 굉장히 간단하고 빠르기 때문에 초창기부터 컴퓨터에 널리 사용되었다. 그러나 선형합동법 은 난수에 주기성이 있고 생성되어 나오는 난수들 사이에 상관 관계가 존재하기 때문에 마지막으로 생성된 난수와 그 외 변수들만 알면 그 다음에 생성될 난수를 모두 예측할 수 있다. 문제는 그 변수들이 ANSI C 표준으로 정해져 있어서 누구든지 다 알 수 있다는 점이다. 즉, 조금 지식이 있는 사람이면 rand 함수의 결과를 보고 다음 난수를 미리 예상할 수 있다는 것이다. 그래서 이 알고리즘은 난수가 예측당해도 상관없는 경우나 임베디드처럼 메모리를 많이 사용하지 못하는 제한된 상황에서 주로 사용한다. 메르센 트위스터(Mersenne Twister) 메르센 트위스터 는 엑셀, MATLAB, PHP, Python, R, C++ 등에서 사용하고 있는 난수 생성 알고리즘이며, 1997년에 마츠모토 마코토 와 니시무라 다쿠지 가 개발한 알고리즘이다. 메르센 트위스터라는 이름은 이 알고리즘의 난수 반복 주기가 메르센 소수 인데서 유래했다. 메르센 소수라고 하면 뭔가 대단한 수 같은데 사실 별 거 없다. 메르센 수 는 M n = 2 n − 1 M_n = 2^{n} - 1 Mn​=2n−1으로 나타내며 식 그대로 2의 n제곱에서 1이 모자란 수 를 말하는 것이고 메르센 소수 는 그냥 이 메르센 수 중에서 소수인 것을 고른 것이다. 보통 2 19937 − 1 2^{19937} - 1 219937−1의 난수 반복 주기를 가지는 MT19937 이 많이 사용되는데, C++에서도 이 알고리즘을 채택해서 사용하고 있다. 이 알고리즘의 동작 원리를 간단하게 설명하면 다음과 같다. seed를 사용하여 624 만큼의 길이를 가진 벡터를 생성. seed는 보통 하드웨어 노이즈나 오늘 날짜를 사용한다. 이 벡터를 사용하여 624개의 유사 난수를 만든다. 이 벡터에 노이즈를 준 후 다시 2번을 반복. 이 노이즈를 주는 행위를 Twist한다고 한다. 이때 3번의 Twist 하는 과정에서 GFSR(Generalized Feedback Shift Register 라는 방법을 사용한다. GFSR 은 자료가 많지 않고 대부분 논문같은 학술 자료만 있는 상황이라 필자가 자세히 알아보지는 못했으나, 열심히 구글링하고 논문들을 뜯어본 결과 LFSR(Linear Feedback Shift Register) 를 약간 변형한 방법이라는 정보를 얻을 수 있었다. (정보가 너무 제한적이라 LFSR 기반이 맞는지는 정확하지 않다.) LFSR 은 이전 상태 값들을 가져와서 선형 함수를 통해 계산한 후 그걸 사용해서 다음 값을 만들어 내는 방법이다. 이때 사용하는 함수는 보통 XOR 를 많이 사용하고 맨 처음 값을 시드(Seed) 라고 부른다. LFSR 를 간단히 설명하자면, 우선 몇개의 메모리 주소를 골라놓고 초기화된 인풋인 시드를 레지스터에 밀어넣는다. 그러면 오른쪽으로 한칸씩 비트가 밀리게(Shifting) 된다. 그러면 우리는 끝에서 삐져나온 한개의 비트를 아웃풋에서 얻게 된다. 그 다음 미리 골라놨던 메모리 주소에 접근해서 값을 빼온 다음에 순서대로 하단에 위치한 3개의 XOR 게이트에 통과시키면 다음 인풋이 나오고 그걸 또 레지스터에 밀어넣는걸 반복하는 것이다. 메르센 트위스터도 결국은 LFSR 가 약간 변형된 GFSR 를 사용하여 난수를 생성하기 때문에 초반에 시드를 생성해줘야한다. 메르센 트위스터의 자세한 알고리즘은 위키피디아의 Mersenne Twister - Algorithmic_detail에서 확인할 수 있다. 필자는 2002년에 마츠모토 마코토 와 니시무라 다쿠지 가 자신들의 메르센 트위스터 알고리즘을 개선해서 다시 작성한 C의 MT19937 알고리즘 코드를 보고 자바스크립트로 한번 포팅해보았다. 이 코드는 최대 32bit 길이의 난수를 사용하도록 작성되어있다. 64bit용 알고리즘은 MT19937-64 라고 또 따로 있다. const N = 624 ; const M = 397 ; const F = 1812433253 ; const UPPER_MASK = ( 2 ** 32 ) / 2 ; const LOWER_MASK = UPPER_MASK - 1 ; const MATRIX_A = 0x9908b0df ; class MersenneTwister { constructor ( ) { const initSeed = new Date ( ) . getTime ( ) ; this . mt = new Array ( N ) ; this . index = N + 1 ; this . seedMt ( initSeed ) ; } seedMt ( seed ) { let s ; this . mt [ 0 ] = seed >>> 0 ; for ( this . index = 1 ; this . index < N ; this . index ++ ) { this . mt [ this . index ] = F * ( this . mt [ this . index - 1 ] ^ ( this . mt [ this . index - 1 ] ) >>> 30 ) + this . index ; this . mt [ this . index ] &= 0xffffffff ; } } int ( ) { let y ; const mag01 = new Array ( 0 , MATRIX_A ) ; if ( this . index >= N ) { let kk ; if ( this . index === N + 1 ) { this . seedMt ( 5489 ) ; } for ( kk = 0 ; kk < N - M ; kk ++ ) { y = ( this . mt [ kk ] & UPPER_MASK ) | ( this . mt [ kk + 1 ] & LOWER_MASK ) ; this . mt [ kk ] = this . mt [ kk + M ] ^ ( y >>> 1 ) ^ mag01 [ y & 1 ] ; } for ( ; kk < N - 1 ; kk ++ ) { y = ( this . mt [ kk ] & UPPER_MASK ) | ( this . mt [ kk + 1 ] & LOWER_MASK ) ; this . mt [ kk ] = this . mt [ kk + ( M - N ) ] ^ ( y >>> 1 ) ^ mag01 [ y & 1 ] ; } y = ( this . mt [ N – 1 ] & UPPER_MASK ) | ( this . mt [ 0 ] & LOWER_MASK ) ; this . mt [ N – 1 ] = this . mt [ M – 1 ] ^ ( y >>> 1 ) ^ mag01 [ y & 1 ] ; this . index = 0 ; } y = this . mt [ this . index ++ ] ; y ^= ( y >>> 11 ) ; y ^= ( y << 7 ) & 0x9d2c5680 ; y ^= ( y << 15 ) & 0xefc60000 ; y ^= ( y >>> 18 ) ; return y >>> 0 ; } ; }

코드 내부에 사용된 상수 F = 1812433253 , MATRIX_A = 0x9908b0df , this.seedMt(5489) 등은 필자가 임의로 넣은 수가 아니라 MT19937 의 표준 계수로 정해져 있는 수이다.

사실 알고리즘 자체가 너무 복잡해서 필자도 다 이해하지는 못했다. (대학 때 공부를 열심히 안한 죄…) 그래도 일단 이렇게 코드로 한번 직접 작성해보면 글로만 읽을 때보다는 확실히 조금 더 이해가 되기 때문에 C로 작성된 원래 코드를 자바스크립트로 포팅한 것이다. 필자가 참고한 C 라이브러리 코드는 여기서 확인할 수 있다.

const rand = new MersenneTwister ( ) ; console . log ( rand . int ( ) ) ;

작성한 코드를 직접 실행해보니 랜덤한 난수가 잘 생성이 되는 것 같다. 사실 난수가 잘 생성되는지 정확하게 보려면 결과를 시각화한 후 난수의 분포도를 봐야하지만 귀찮은 관계로 일단 패스하겠다. 참고로 이 알고리즘을 만든 마츠모토 마코토의 홈페이지에 들어가면 이 알고리즘이 왜 이런 이름을 가지게 되었는지 나와있다.

마코토: Knuth 교수님이 이 이름 발음하기 너무 힘들대.

다쿠지: … [며칠 후] 마코토: 하이 타쿤, 메르센 트위스터는 어때? 메르센 소수를 사용하기도 했고, 원형은 Twisted GFSR(Generalized Feedback Shift Register)니까.

다쿠지: 글쎄…?

마코토: 왠지 제트코스터 같이 들리는 걸? 빨라보이기도 하고 기억하고 쉽고 발음하기 좋고. 그리고 이건 비밀인데 이 이름엔 우리들의 이니셜이 숨어있지!(Makoto, Takuji)

다쿠지: …

마코토: 자자자 MT로 가는거다?

다쿠지: 음…그래 나중에 우리는 Knuth 교수님으로부터 “좋은 이름인 것 같다”라는 편지를 받았다.

뭔가 깨발랄한 마코토형과 시니컬한 다쿠지형 케미가 돋보인다. 뭔가 이런 대단한 알고리즘을 개발한 사람이지만 사람 냄새나는 네이밍 과정인듯.

XOR 시프트(XOR shift)

XOR 시프트 도 메르센 트위스터와 마찬가지로 Linear Feedback Shift Register 을 기반으로 한 의사 난수 알고리즘이다. 어떻게 보면 메르센 트위스트의 하위호환이라고 볼 수도 있는데, 메르센 트위스트와 원리는 비슷하지만 구현이 훨씬 간단하고 작동이 빠르기 때문에 왕왕 사용된다.

XOR 시프트 알고리즘은 여러 종류가 있는데, 32bit , 64bit , 128bit 의 수를 사용하며 각각 2 32 − 1 2^{32} -1 232−1, 2 64 − 1 2^{64} – 1 264−1, 2 128 − 1 2^{128} – 1 2128−1의 메르센 수 난수 반복 주기를 가진다.

근데 이게 TestU01 이라는 난수 품질 테스트 프레임워크의 테스트를 통과하지 못해서 조금 문제가 있었다. 이걸 통과해야 ANSI C 표준이 될 수 있기 때문이다.

그래서 몇가지 변종 알고리즘이 나오게 되었는데 그 중 하나가 128bit 를 사용하는 XOR 시프트 128 을 개량한 XOR 시프트 128 + 라는 알고리즘이다. (뭔가 게임 후속작 제목 같다…)

참고로 V8 , SpdierMonkey , JavaScriptCore 등 메이저 자바스크립트 엔진들이 채택한 난수 생성 알고리즘이 XOR 시프트 128 + 이다. 이 알고리즘은 2016년 11월에 Sebastiano Vigna 라는 분에 의해 학회에서 발표되었다. 논문 내용은 여기에서 확인할 수 있다.

전반적인 원리는 위에서 설명한 LFSR 와 비슷하니, V8 엔진에서 Math.random 메소드를 어떻게 구현했는지 한번 살펴보자. 원래 코드는 C++로 작성되어있으나 여러분이 브라우저에서 코드를 쉽게 실행시켜볼 수 있도록 동일한 로직을 자바스크립트로 포팅해서 작성하겠다.

V8 내부 소스 코드는 v8/src/base/utils/random-number-generator.h 의 XorShift128 메소드에 작성되어 있다.

const state = [ 1827981275 , 1295982171 ] ; function xorshift128plus ( ) { let s1 = state [ 0 ] ; let s0 = state [ 1 ] ; state [ 0 ] = s0 ; s1 ^= s1 << 23 ; s1 ^= s1 >> 17 ; s1 ^= s0 ; state [ 1 ] = s1 ; console . log ( ‘레지스터의 현재 상태 -> ‘ , state ) ; return state [ 0 ] + state [ 1 ] ; } console . log ( ‘초기 레지스터 상태 -> ‘ , state ) ; for ( let i = 0 ; i < 5 ; i ++ ) { console . log ( '난수 -> ‘ , xorshift128plus ( ) ) ; }

초기 레지스터 상태 – > [ 1827981275 , 1295982171 ] 레지스터의 현재 상태 – > [ 1295982171 , 867440954 ] 난수 – > 2163423125 레지스터의 현재 상태 – > [ 867440954 , 1393243966 ] 난수 – > 2260684920 레지스터의 현재 상태 – > [ 1393243966 , 37812574 ] 난수 – > 1431056540 레지스터의 현재 상태 – > [ 37812574 , 833890405 ] 난수 – > 871702979 레지스터의 현재 상태 – > [ 833890405 , 1661667227 ] 난수 – > 2495557632

출력된 로그를 보면 레지스터의 상태가 어떻게 변하고 있는지 알 수 있다.

[1] 번 인덱스에 있던 값이 [0] 번 인덱스로 옮겨지고 [1] 번 인덱스에 새로운 난수를 꽂아넣은 후 두 원소를 더해서 출력하고 있다는 걸 알 수 있다.

계산 과정을 보면 [1] 번 인덱스에 새로운 값을 넣을 때는 시프팅되어 왼쪽으로 삐져나온 값인 [0] 번 인덱스의 값을 사용하여 XOR 시프팅 을 진행하고 그 값을 다시 [1] 번 인덱스에 넣어준다.

그리고 시프팅하는 상수인 23 , 17 은 XOR 시프팅 128+ 알고리즘을 개발할 때 연구를 통해 찾아낸 최적의 상수이기 때문에 사용하는 것이다. 해당 논문을 보면 뭐 이것저것 시도해본 다음에 결과를 일일히 테스트해서 나온 결과를 비교한 도표도 함께 첨부되어있다.

마치며

사실 처음에는 가벼운 마음으로 랜덤 에 대한 이야기를 해보려고 했는데 예상보다 수학적인 내용이 많이 나와서 왠지 어려운 포스팅이 되어버린 것 같다.

사실 컴퓨터라는 계산기로 진정한 의미의 난수를 만드는 것은 거의 불가능하다. 최근에 미국에서 양자컴퓨터를 사용해서 진정한 의미의 난수를 생성하는 데 성공했다고 하지만 양자컴퓨터는 아직은 우리와 너무나도 먼 이야기이기 때문에 논외로 치겠다.

필자도 사실 수학을 그다지 좋아하는 편은 아니다. 하지만 이렇게 수학적인 연구를 통해 생성 규칙이 없는 난수 를 만드려는 많은 사람들의 도전을 보면, 편하게 상위 레이어에서 코딩하고 있는 필자로써는 이 분들에게 굉장히 감사함을 느낀다. (난 안될꺼야 아마…)

연구원 분들이 기반 알고리즘을 만들어주시면 열심히 상용 어플리케이션에 써먹겠습니다…!!!

필자는 이 포스팅을 작성하면서 논문과 위키피디아를 엄청 들여다봤는데 오랜만에 영어와 수식을 너무 많이 봐서 머리에 과부하가 걸린 상태다. 그리고 다른 건 몰라도 메르센 트위스트 같은 경우는… 아니 너무 복잡하다 인간적으로…

참고로 이거 만든 마츠모토 마코토 님은 지금 히로시마 대학교의 수학 대학원에서 조교수로 근무하고 계신데, 이 정도 머리가 되야 강단에 설 수 있는 건가라는 생각도 든다. 완전 어나더레벨…

이상으로 컴퓨터가 만드는 랜덤은 정말로 랜덤할까? 포스팅을 마친다.

참고문헌

XorShift – Wikipedia

There’s Math.random(), and then There’s Math.random() – V8 Dev

Futher scramblings of Marsaglia’s xorshift generators – Sebastiano Vigna

The Xorshit128+ random number generator fails BigCrush – Daniel Lemire

So you have finished reading the 난수 발생 topic article, if you find this article useful, please share it. Thank you very much. See more: c언어 난수 생성, 난수발생기 엑셀, 난수 생성 원리, 난수생성 알고리즘, 난수 생성 사이트, 난수생성 프로그램, 난수란, 랜덤 숫자 생성

Leave a Comment