출처 :http://www.getmeout.co.kr/main/main.asp?part=board&boardpart=list&idx=1412&page=1&countnum=767&l_id=11&m_id=7

오라클 vs MS SQL 함수 비교..

수식/수치 연산 함수

다음은 Oracle에서 지원하는 수식/수치 연산 함수와 그에 상응하는 Microsoft SQL Server의 함수를 정리한 표입니다.

함수 설명 Oracle Microsoft SQL Server
절대 값 ABS ABS
아크 코사인 ACOS ACOS
아크 사인 ASIN ASIN
n의 아크 탄젠트 ATAN ATAN
n과 m의 아크 탄젠트 ATAN2 ATN2
최소 정수 >= 값 CEIL CEILING
코사인 COS COS
쌍곡선 코사인 COSH COT
지수 값 EXP EXP
최대 정수 <= 값 FLOOR FLOOR
자연 로그 LN LOG
밑이 n인 로그 LOG(N) 해당 없음
상용 로그 LOG(10) LOG10
나머지 연산자 MOD USE MODULO (%) OPERATOR
거듭제곱 POWER POWER
난수 해당 없음 RAND
반올림 ROUND ROUND
숫자 부호 표시 SIGN SIGN
사인 SIN SIN
쌍곡선 사인 SINH 해당 없음
제곱근 SQRT SQRT
탄젠트 TAN TAN
쌍곡선 탄젠트 TANH 해당 없음
잘라내기 TRUNC 해당 없음
목록의 최대값 GREATEST 해당 없음
목록의 최소값 LEAST 해당 없음
NULL일 때 숫자 변환 NVL ISNULL

문자열 함수

다음은 Oracle에서 지원하는 문자열 함수 및 그에 상응하는 Microsoft SQL Server의 함수를 정리한 표입니다.

함수 설명 Oracle Microsoft SQL Server
문자를 ASCII로 변환 ASCII ASCII
문자열 연결 CONCAT ( + )
ASCII를 문자로 변환 CHR CHAR
문자열의 문자 시작 위치 반환(왼쪽부터) INSTR CHARINDEX
소문자로 변환 LOWER LOWER
대문자로 변환 UPPER UPPER
문자열의 왼쪽 채우기 LPAD 해당 없음
선행 공백 제거 LTRIM LTRIM
후행 공백 제거 RTRIM RTRIM
문자열의 패턴 시작 위치 INSTR PATINDEX
문자열을 여러 번 반복 RPAD REPLICATE
문자열의 발음 기호 SOUNDEX SOUNDEX
반복되는 공백 문자열 RPAD SPACE
수치 데이터에서 변환된 문자 데이터 TO_CHAR STR
부분 문자열 SUBSTR SUBSTRING
문자 바꾸기 REPLACE STUFF
문자열에서 각 단어의 첫 문자를 대문자로 만들기 INITCAP 해당 없음
문자열 번역 TRANSLATE 해당 없음
문자열 길이 LENGTH DATELENGTH 또는 LEN
목록에서 가장 큰 문자열 GREATEST 해당 없음
목록에서 가장 작은 문자열 LEAST 해당 없음
NULL일 때 문자열 변환 NVL ISNULL

날짜 함수

다음은 Oracle에서 지원하는 날짜 함수 및 그에 상응하는 Microsoft SQL Server의 함수를 정리한 표입니다.

함수 설명 Oracle Microsoft SQL Server
날짜 추가 (날짜 열의 +/- 값) 또는 ADD_MONTHS DATEADD
날짜 차이 (날짜 열의 +/- 값) 또는 MONTHS_BETWEEN DATEDIFF
현재 날짜와 시간 SYSDATE GETDATE()
달의 마지막 날 LAST_DAY 해당 없음
표준 시간대 변환 NEW_TIME 해당 없음
다음 날의 요일 NEXT_DAY 해당 없음
날짜의 문자열 표시 TO_CHAR DATENAME
날짜의 정수 표시 TO_NUMBER(TO_CHAR)) DATEPART
날짜 반올림 ROUND CONVERT
날짜 잘라내기 TRUNC CONVERT
문자열을 날짜로 TO_DATE CONVERT
NULL일 때 날짜 변환 NVL ISNULL

변환 함수

다음은 Oracle에서 지원하는 변환 함수 및 그에 상응하는 Microsoft SQL Server의 함수를 정리한 표입니다.

함수 설명 Oracle Microsoft SQL Server
숫자를 문자로 TO_CHAR CONVERT
문자를 숫자로 TO_NUMBER CONVERT
날짜를 문자로 TO_CHAR CONVERT
문자를 날짜로 TO_DATE CONVERT
16진수를 이진수로 HEX_TO_RAW CONVERT
이진수를 16진수로 RAW_TO_HEX CONVERT

기타 행 수준 함수

다음은 Oracle에서 지원하는 기타 행 수준 함수 및 그에 상응하는 Microsoft SQL Server의 함수를 정리한 표입니다.

함수 설명 Oracle Microsoft SQL Server
NULL이 아닌 첫째 식 반환 DECODE COALESCE
현재 시퀀스 값 CURRVAL 해당 없음
다음 시퀀스 값 NEXTVAL 해당 없음
식1 = 식2일 때 NULL 반환 DECODE NULLIF
사용자의 로그인 ID 번호 UID SUSER_ID
사용자의 로그인 이름 USER SUSER_NAME
사용자의 데이터베이스 ID 번호 UID USER_ID
사용자의 데이터베이스 이름 USER USER_NAME
현재 사용자 CURRENT_USER CURRENT_USER
사용자 환경(감사 추적) USERENV 해당 없음
CONNECT BY 절의 수준 LEVEL 해당 없음

집계 함수

다음은 Oracle에서 지원하는 집계 함수 및 그에 상응하는 Microsoft SQL Server의 함수를 정리한 표입니다.

함수 설명 Oracle Microsoft SQL Server
평균 AVG AVG
개수 COUNT COUNT
최대값 MAX MAX
최소값 MIN MIN
표준 편차 STDDEV STDEV 또는 STDEVP
합계 SUM SUM
분산 VARIANCE VAR 또는 VARP

조건부 테스트

Oracle DECODE 문과 Microsoft SQL Server CASE 식 모두 조건부 테스트를 수행합니다. 테스트_값의 값이 그 다음에 오는 어떤 식과 일치하면 관련 값이 반환됩니다. 일치하지 않으면 기본_값이 반환됩니다. 기본_값이 지정되어 있지 않고 일치하는 식이 없으면 DECODE와 CASE는 NULL을 반환합니다. 다음 표는 변환된 DECODE 명령 예제를 비롯하여 구문을 정리한 것입니다.

Oracle Microsoft SQL Server
DECODE (테스트_값,
식1, 값1
[[,식2, 값2] [U]]
[,기본_값]
)

CREATE VIEW STUDENT_ADMIN.STUDENT_GPA
(SSN, GPA)
AS SELECT SSN, ROUND(AVG(DECODE(grade
,'A', 4
,'A+', 4.3
,'A-', 3.7
,'B', 3
,'B+', 3.3
,'B-', 2.7
,'C', 2
,'C+', 2.3
,'C-', 1.7
,'D', 1
,'D+', 1.3
,'D-', 0.7
,0)
),2)
FROM STUDENT_ADMIN.GRADE
GROUP BY SSN
CASE 입력_식
WHEN when_식 THEN 결과_식
[[WHEN when_식 THEN 결과_식] [...]]
[ELSE else_결과_식]
END

CREATE VIEW STUDENT_ADMIN.STUDENT_GPA
(SSN, GPA)
AS SELECT SSN, ROUND(AVG(CASE grade
WHEN 'A' THEN 4
WHEN 'A+' THEN 4.3
WHEN 'A-' THEN 3.7
WHEN 'B' THEN 3
WHEN 'B+' THEN 3.3
WHEN 'B-' THEN 2.7
WHEN 'C' THEN 2
WHEN 'C+' THEN 2.3
WHEN 'C-' THEN 1.7
WHEN 'D' THEN 1
WHEN 'D+' THEN 1.3
WHEN 'D-' THEN 0.7
ELSE 0
END),2)
FROM STUDENT_ADMIN.GRADE
GROUP BY SSN

CASE 식은 SELECT 문을 사용하여 부울 테스트를 수행할 수 있도록 지원합니다. DECODE 명령은 이를 허용하지않습니다. CASE 식에 대한 자세한 내용은 SQL Server 온라인 설명서를 참조하십시오.

값을 다른 데이터 형식으로 변환

Microsoft SQL Server의 CONVERT 및 CAST 함수는 다목적 변환 함수입니다. 이들은 비슷한 기능을 제공하며 식을 다른 데이터 형식으로 변환하고 다양한 특수 날짜 형식을 지원합니다.

  • CAST(식 AS 데이터_형식)
  • CONVERT (데이터 형식[(길이)], 식 [, 스타일])

CAST는 SQL-92 표준 함수입니다. 이들 함수는 Oracle의 TO_CHAR, TO_NUMBER, TO_DATE, HEXTORAW 및 RAWTOHEX 함수와 같은 작업을 수행합니다.

데이터 형식은 식을 변환할 모든 시스템 데이터 형식입니다. 사용자 정의 데이터 형식은 사용할 수 없습니다. 길이 매개 변수는 선택 사항이며 char, varchar, binaryvarbinary 데이터 형식과 함께 사용됩니다. 허용되는 최대 길이는 8000입니다.

변환 Oracle Microsoft SQL Server
문자를 숫자로 TO_NUMBER('10') CONVERT(numeric, '10')
숫자를 문자로 TO_CHAR(10) CONVERT(char, 10)
문자를 날짜로 TO_DATE('04-JUL-97')
TO_DATE('04-JUL-1997',
'dd-mon-yyyy')
TO_DATE('July 4, 1997',
'Month dd, yyyy')
CONVERT(datetime, '04-JUL-97')
CONVERT(datetime, '04-JUL-1997')
CONVERT(datetime, 'July 4, 1997')
날짜를 문자로 TO_CHAR(sysdate)
TO_CHAR(sysdate, 'dd mon yyyy')
TO_CHAR(sysdate, 'mm/dd/yyyy')
CONVERT(char, GETDATE())
CONVERT(char, GETDATE(), 106)
CONVERT(char, GETDATE(), 101)
16진수를 이진수로 HEXTORAW('1F') CONVERT(binary, '1F')
이진수를 16진수로 RAWTOHEX
(binary_column)
CONVERT(char, 이진_열)

문자열이 어떻게 날짜로 변환되는지 눈여겨 보십시오. Oracle의 기본 날짜 형식 모델은 "DD-MON-YY"입니다. 다른 형식을 사용하는 경우 적절한 날짜 형식 모델을 제공해야 합니다. CONVERT 함수는 형식 모델을 필요로 하지 않고 자동으로 표준 날짜 형식을 변환합니다.

날짜를 문자열로 변환하면 CONVERT 함수의 기본 출력은 "dd mon yyyy hh:mm:ss:mmm(24h)"이 됩니다. 숫자 스타일 코드는 출력 형식을 다른 종류의 데이터 형식 모델로 지정하는 데 사용됩니다. CONVERT 함수에 대한 자세한 내용은 SQL Server 온라인 설명서를 참조하십시오.

아래 표는 Microsoft SQL Server 날짜의 기본 출력을 정리한 것입니다.

세기 사용 안함 세기 사용 표준 출력
- 0 또는 100 (*) 기본값 mon dd yyyy hh:miAM(또는 PM)
1 101 미국 mm/dd/yy
2 102 ANSI yy.mm.dd
3 103 영국/프랑스 dd/mm/yy
4 104 독일 dd.mm.yy
5 105 이탈리아 dd-mm-yy
6 106 - dd mon yy
7 107 - mon dd, yy
8 108 - hh:mm:ss
- 9 또는 109 (*) 기본 밀리초 mon dd yyyy hh:mi:ss:mmm(AM 또는 PM)
10 110 미국 mm-dd-yy
11 111 일본 yy/mm/dd
12 112 ISO yymmdd
- 13 또는 113 (*) 유럽 기본값 dd mon yyyy hh:mm:ss:mmm(24h)
14 114 - hh:mi:ss:mmm(24h)

사용자 정의 함수

Oracle PL/SQL 함수는 Oracle SQL 문에 사용할 수 있습니다. Microsoft SQL Server에서는 보통 다른 방법을 사용하여 이 기능을 얻을 수 있습니다.

아래 예제에서는 Oracle의 사용자 정의 함수 GET_SUM_MAJOR를 사용하여 학생들이 지불하는 수업료의 합계를 냅니다. SQL Server에서는 쿼리를 테이블로 사용하여 이렇게 할 수 있습니다.

Oracle Microsoft SQL Server
SELECT SSN, FNAME, LNAME, ) TUITION_PAID,
TUITION_PAID/GET_SUM_MAJOR(MAJOR)
AS PERCENT_MAJOR
FROM STUDENT_ADMIN.STUDENT
SELECT SSN, FNAME, LNAME, TUITION_PAID, TUITION_PAID/SUM_MAJOR AS PERCENT_MAJOR
FROM STUDENT_ADMIN.STUDENT,
(SELECT MAJOR, SUM(TUITION_PAID) SUM_MAJOR
FROM STUDENT_ADMIN.STUDENT
GROUP BY MAJOR) SUM_STUDENT
WHERE STUDENT.MAJOR = SUM_STUDENT.MAJOR
CREATE OR REPLACE FUNCTION GET_SUM_MAJOR
(INMAJOR VARCHAR2) RETURN NUMBER
AS SUM_PAID NUMBER;
BEGIN
SELECT SUM(TUITION_PAID) INTO SUM_PAID
FROM STUDENT_ADMIN.STUDENT
WHERE MAJOR = INMAJOR;
RETURN(SUM_PAID);
END GET_SUM_MAJOR;
CREATE FUNCTION 구문이 필요하지 않습니다. CREATE PROCEDURE 구문을 사용하십시오.

Oracle과 Microsoft SQL Server의 비교 연산자는 거의 같습니다.

연산자 Oracle Microsoft SQL Server
같음 (=) (=)
(>) (>)
작음 (<) (<)
크거나 같음 (>=) (>=)
작거나 같음 (<=) (<=)
같지 않음 (!=, <>, ^=) (!=, <>, ^=)
크지 않음, 작지 않음 해당 없음 !> , !<
집합의 구성원에 있음 IN IN
집합의 구성원에 없음 NOT IN NOT IN
집합에 있는 임의의 값 ANY, SOME ANY, SOME
집합에 있는
모든 값
!= ALL, <> ALL, < ALL,
> ALL, <= ALL, >= ALL, != SOME, <> SOME,
< SOME, > SOME,
<= SOME, >= SOME
!= ALL, <> ALL, < ALL,
> ALL, <= ALL, >= ALL, != SOME, <> SOME,
< SOME, > SOME,
<= SOME, >= SOME
패턴과 같음 LIKE LIKE
패턴과 같지 않음 NOT LIKE NOT LIKE
x와 y 사이의 값 BETWEEN x AND y BETWEEN x AND y
사이에 있지 않은 값 NOT BETWEEN NOT BETWEEN
값이 있음 EXISTS EXISTS
값이 없음 NOT EXISTS NOT EXISTS
값이 NULL이거나 NULL이 아님 IS NULL, IS NOT NULL 같습니다. 이전 버전과의 호환성을 위해 = NULL,
!= NULL도 사용할 수 있지만 권장되지 않습니다.

패턴 일치

SQL Server의 LIKE 키워드는 Oracle은 지원하지 않는 유용한 와일드카드 검색 옵션을 제공합니다. SQL Server는 양쪽 RDBMS에 공통된 % 및 _ 와일드카드 문자를 지원함은 물론 [ ] 및 [^] 문자도 지원합니다.

[ ] 문자 집합은 지정한 범위에서 단일 문자를 검색하는 데 사용합니다. 예를 들어, 단일 문자 위치에서 a부터 f까지의 문자를 검색하는 경우 LIKE '[a-f]' 또는 LIKE '[abcdef]'처럼 지정할 수 있습니다. 아래 표를 통해 이러한 추가 와일드카드 문자의 유용함을 확인할 수 있습니다.

Oracle Microsoft SQL Server
SELECT * FROM STUDENT_ADMIN.STUDENT
WHERE LNAME LIKE 'A%'
OR LNAME LIKE 'B%'
OR LNAME LIKE 'C%'
SELECT * FROM STUDENT_ADMIN.STUDENT
WHERE LNAME LIKE '[ABC]%'

[^] 와일드카드 문자 집합은 지정된 범위에 NOT 문자를 지정할 때 사용합니다. 예를 들어, a부터 f까지를 제외한 모든 문자가 허용될 때 LIKE '[^a - f]' 또는 LIKE '[^abcdef]'를 사용합니다.

첨부파일이 없습니다.

 

Posted by 패스맨

댓글을 달아 주세요


출처 : http://www.gamedevforever.com/114


안녕하세요. 알콜코더 민군입니다.

현재 제작 중인 게임에서, 랜덤 시드 값을 일치 시켜서, 랜덤 결과를 서로 다른 클라이언트끼리 동기화 시키는 작업을 진행 하였습니다. 랜덤 시드값만 서로 일치시키면, 이후에 생성되는 랜덤 함수의 결과값들은 모두 일치가 되기 때문에, 예전에 스타크래프트와 같은 패키지 게임에서 자주 사용했던 테크닉입니다. ^^; 서로 다른 클라이언트끼리 처음 시드값만 일치 시키면, 이후의 랜덤값은 정해져 있기 때문에, 그 랜덤값을 사용한 이벤트등의 동기화에 사용하는 것이죠.

이런 테크닉은 패키지 게임 시절에는 리플레이 저장이나 네트워크 동기화등에서 상당히 많이 사용하였습니다. 하지만 온라인 게임으로 넘어오면서, 대부분 서버에서 랜덤값을 직접 생성하여 넘겨주기 때문에, 이 테크닉 쓸일이 거의 없었는데… 이번 상황은 랜덤값이 게임의 결과에 전혀 영향을 끼치 않고, 단지 연출에만 영향을 끼치기 때문에 이 테크닉을 사용하기로 하였습니다. (서버 부담을 줄여달라는 서버쪽의 간절한 요청 때문에.. 아흑..OTL)

일반적으로 랜덤 함수라면 C++ 표준 rand() 함수를 사용하게 됩니다. 뭐.. 일반적인 랜덤값을 사용하는 경우에는 사실 이 표준 함수를 사용해도, 별 문제는 없습니다. ^^; 하지만 위와 같은 테크닉을 사용할 때는 rand() 함수를 사용하면 안됩니다!

왜냐하면, C++의 표준 rand() 함수는 아래와 같은 약간의 문제점을 가지고 있습니다.

  1. rand() 함수의 분포는 그리 고르지 않다. 특히 작은 표본을 사용할때는 더욱 그렇다.
    즉, 이말은 1~10까지 랜덤을 1억번쯤 돌리면, 확률이 다들 비슷하게 나오긴 하지만, 10번 정도만 돌릴때에는 1 하나만 10번이 나온다거나 하는 가능성이 있다는 것입니다.

  2. rand() 함수는 전역 함수이다. 어디서든 사용이 가능하다
    이 함수는 표준 함수이기 때문에, 코드의 어디에서도 호출이 가능합니다. 그래서 호출 되는 경우를 제어할 수 가 없습니다.

< 즉 이런 기적의 확률이 나올수도 있는거임.. ㅠ.ㅠ >

저의 경우에 문제가 되는 것은 1번이 아니라, 2번입니다. 같은 랜덤 시드값으로 서로 다른 클라이언트에서, 싱크를 맞추기 위해서는 랜덤 호출 횟수가 정확히(!) 일치하여야 합니다! 내가 랜덤함수를 5번 호출했으면, 상대방도 5번 호출해야 같은 결과 값이 나와서 싱크가 일치하게 됩니다.

그런데 만약? 내가 작성한 코드가 아니라 어딘가 다른 코드에서 그것도 한쪽 클라이언트에서만 그 사이에 rand()를 호출하게 되면 어떻게 될까요? 넵. 당연히 그 다음부터는 모든 싱크가 아작이 나게됩니다…(그리고 이 경우에는 어디서부터 문제가 발생 했는지 찾는 것도 거의 불가능)

전역 함수라는 특징 때문에, 어디서 어떻게 불리울지 모르기 때문에, 언제 호출 횟수가 어긋날지 모른다는 문제가 발생하기 때문에, 랜덤 시드로 씽크를 맞추는 이 테크닉에서는 rand() 함수를 사용하는 것은 불가능 합니다. (내 코드에서는 절대 그럴리가 없어! 라고 해도… 다른 사람이 작성한 코드에서 과연 부르지 않는다는 보장이 있을까요…)

그래서 따로 랜덤 생성 클래스를 만들어 사용하게 됩니다. 랜덤 클래스를 만들고 그 인스턴스만을 사용하게 되면, 호출 횟수가 어긋나는 문제를 해결할 수 있으니까요. ^^

저의 경우가 바로 이런 경우라서, 랜덤 생성 알고리즘을 한번 찾아 봤습니다. 랜덤 생성 알고리즘은 "난수 생성기(Random Number Generator)", 혹은 "의사 난수 생성기" 등으로 불리웁니다. (그냥 저는 편의를 위해.. 이후 '랜덤 생성기'라고 칭하겠습니다. 이게 걍 편해요…)

이렇게 따로 랜덤 생성기를 이용해서, 랜덤 생성 클래스를 만들어 사용하면, 위와 같이 코드의 다른곳에서 랜덤값이 불리우는 경우를 제어할 수 있습니다. 물론 그렇다고 랜덤 생성 알고리즘을 혼자 고급 수학책이나 물리책 펴놓고 만들어서 쓰라는 이야기는 아닙니다. 친절하게도 이런 알고리즘은 전문 수학자 분들이 편하게 갖다 쓸수 있도록 편하고도 멋지게 만들어 두었습니다. (아이구~ 이런 감사할때가….)

이런 랜덤 생성기중에서 가장 유명하고 널리 쓰이는 알고리즘이 바로 [메르센 트위스터(MT.Mersenne Twister)][WELL]이라는 랜덤 생성기입니다.

그리고 이 랜덤 생성기들은 위와 같은 테크닉에 사용할 수 있는 용도 외에도 다음과 같은 뛰어난 장점들을 가지고 있습니다

  1. 표준 함수보다 랜덤 분포가 훨씬 고르다

    표준 함수의 경우 2^32승의 period를 가지는데 반해, MT의 경우는 2^19937-1를 가집니다. 그리고 623차원까지 동일분포 되어 있습니다. (자세한건 아래 링크 참조)

  2. 표준 함수보다 훨씬 속도가 빠르다.

    MT의 경우에 비트 연산만으로 구현되어 있어서, 표준 rand()보다 약 4배가 빠르다고 합니다. 그리고 WELL 같은 경우에는 MT보다 40%가 더 빠르다고 합니다.

메르센 트위스터

위키백과, 우리 모두의 백과사전.

메르센 트위스터(Mersenne Twister) 1997년에 마츠모토 마코토(松本 ) 니시무라 다쿠지(西村拓士) 개발한 유사난수 생성기이다.[1] 메르센 트위스터는 동일한 저자들이 개발한 TT800 생성기의 개선판으로, 기존 생성기들의 문제점들을 피하면서 매우 질이 좋은 난수를 빠르게 생성할 있도록 설계되었다.

메르센 트위스터의 이름은 난수의 반복 주기가 메르센 소수 데에서 유래했다. 메르센 트위스터는 속도와 난수의 품질 때문에 점점 많은 곳에서 채택되고 있으며, 흔히 주기가 219937 − 1 MT19937 사용한다. MT19937 같으나 생성해 내는 난수가 32비트가 아닌 64비트인MT19937-64 쓰이며, 2006년에 동일한 저자들이 발표한 SIMD 기반 메르센 트위스터는 MT19937 비해 대략 정도 빠른 것으로 알려져 있다.

난수의 품질에도 불구하고, 메르센 트위스터는 암호학적으로 안전한 유사난수 생성기 아니다. 난수의 특성(주기, 난수 범위) 알고 있을 유한한 수의 난수( 경우 624)만으로 현재 생성기의 상태를 알아 있으며, 뒤에 나올 난수를 예측해 있다. 암호학적으로안전한 유사난수 생성기를 얻기 위해서는 해시 함수 사용해야 하지만 난수의 생성 속도가 낮아진다. 또는 블룸 블룸 (BBS) 같이 암호학적으로 안전하게 설계된 생성기를 수도 있다.

< 출처 : 위키피디아 >

메르센 트위스터는 현재도 가장 널리 사용되고 있는 랜덤 생성기입니다. C++에서는 Boost에도 이 MT 랜덤 생성기가 구현 되어 있습니다. 또한 MATLAB, Ruby, Python등의 언어에서도 기본 난수 알고리즘으로 채택되어서 사용 되고 있습니다. 뭐 물론 단점이 없는 건 아니지만, 장점이 훨씬 더 크기 때문에 표준으로 채택이 되었겠죠. ^^

그리고 가장 큰 장점은 특별히 따로 구현하지 않아도, Boost에 포함되어 있기 때문에, Boost만 있다면 바로 사용이 가능하다는 장점이 있습니다. 사용 방법에 관해서는 하단의 참조 링크에서 확인하실 수 있습니다.

WELL

WELL은 위 MT의 디자이너가 10년후에 고안한 난수 발생 알고리즘 입니다. 그의 주장에 따르면 MT보다 40% 빠르고 코드도 더 간단합니다. WELL은 분포도에 따라서 WELL512, WELL1024, WELL19947, WELL44497의 종류가 있습니다. 숫자가 클수록 분포도가 높긴 하지만, 게임에서 사용하기엔 512나 1024만으로도 충분할 것 같습니다.

WELL의 구현 코드는 이곳에서 받을 수 있습니다. 실제로 보면 정말 구현은 간단합니다.

아래가 WELL512의 구현 코드입니다.

이게 다입니다. Period는 이름 그대로 2^512입니다. 그렇다 해도 일반 PC로 저걸 세는데 10^100년이 걸린다고 하는군요. 초나 분이 아니라 년 말입니다. (googol years라고 부른다고 하는군요)

사용법은 위의 state만 적절히 초기화 해주고, 함수를 호출하면 32비트 정수(난수)가 리턴됩니다.

간단한 시물레이터로 두 난수 발생기를 시뮬레이팅 해 보았을 때의 차이를 보여드리겠습니다.


C/C++의 rand함수


WELL512 알고리즘

<이미지 출처 : binsoo Blog >

일반적으로 게임 개발할때는 이런 랜덤 생성기까지 필요 하지 않을지도 모릅니다. 그러나 MMORPG와 같이 랜덤이 게임의 밸런스에 큰 영향을 끼치는 경우에는, 서버 측에서 이런 고성능의 랜덤 생성기가 필요한 경우가 많습니다. 유저나 해커가 랜덤값을 함부로 예측해서는 안되니까요. ^^; 그리고 저의 경우 처럼 랜덤 시드를 이용해서 이벤트 동기화를 맞추는 경우에는 전역 함수인 rand()를 사용할 수 없기 때문에 꼭 이런 랜덤 함수가 별도로 필요합니다. 그런 경우에 굳이 이런 좋은 난수 알고리즘들을 놔두고 새로 짜는 고생은 안하는게 낫겠죠.(그렇다고 내가 만든 알고리즘이 저것보다 좋을리는 택도 없을 테니…=ㅅ=;)

< 참고 자료 >

위키피디아 : 메르센 트위스터 [한글]

Generating random numbers in game.[한글]

Boost 라이브러리의 랜덤 함수 이용 [한글]

WELL Random number generator [영문]

Random Number Generation [영문]


출처 :
http://www.gamedevforever.com/114

'Programing > 알고리즘' 카테고리의 다른 글

표준 rand()함수보다 유용한 랜덤 생성 알고리즘 – MT, WELL  (0) 2012.03.07
100개 따조 모으기  (0) 2012.01.16
중복하지 않는 난수생성..  (0) 2011.12.09
Crypt Kicker  (0) 2011.12.07
Jolly Jumpers  (0) 2011.12.07
DisplayLCD  (0) 2011.12.07
Posted by 패스맨

댓글을 달아 주세요


http://www.cse.iitb.ac.in/perfnet/cs456/tcp-state-diag.pdf
Posted by 패스맨

댓글을 달아 주세요