2014년 3월 13일 목요일

[iOS/OSX] 난수 만들기 (Random Number Generation)

Objective-C나 Swift에서 난수 관련된 함수들 이름이 좀 독특해서 잘 외워지지 않기에 메모를 남긴다.

정말 순수한(?) 난수 발생기는 arc4random() 을 이용 할 수 있다.
// Objective-C Example: Generate Random Value
u_int32_t value = arc4random();

// Swift Example: Generate Random Value
let value: UInt32 = arc4random()
발생되는 난수는 0 에서 0x10000000 까지의 정수이다. 만약 0에서 9까지 숫자 중에서 난수를 생성한다면 아래와 같이 사용 할 수도 있다.
// Objective-C Example: Generate Random Value Ranged 0 ~ 9
int value = arc4random() % 10;

// Swift Example: Generate Random Value Ranged 0 ~ 9
let value: UInt32 = arc4random() % 10
위의 코드는 아래와 같은 arc4random_uniform() 함수로 대체가 가능하다.
// Objective-C Example: Generate Random Value Ranged 0 ~ 9
int value = arc4random_uniform(10);

// Swift Example: Generate Random Value Ranged 0 ~ 9
let value: UInt32 = arc4random_uniform(10)
arc4random_uniform(N) 함수는 0 에서 N-1 까지의 정수 난수를 생성한다. 어떻게 보면 가장 자주 사용 할 만한 함수이다.

필요에 따라 실수형 난수가 필요 할 수도 있다. 여기서는 C 표준(?) 함수인 drand48() 이라는 함수를 이용 할 수 있다. drand48() 은 0 에서 1까지의 실수(double 타입)를 생성한다.
// Objective-C Example: Generate Floating Random Value
srand48(time(0));             // seed
double value = drand48();

// Swift Example: Generate Floating Random Value
srand48(time(nil))            // seed
let value: Double = drand48()
여기서는 난수 생성 전에 씨드를 초기화(srand48)했다. 이 씨드는 난수 발생 알고리즘에 관여하는 값으로 만약 난수가 계속 비슷한 패턴으로 발생한다면 이와 같이 씨드를 현재시간(time(0))을 이용해 재설정 해 줌으로써 다른 난수 패턴이 나타나게 할 수 있다.

실수형으로 생성하면 재가공하는데 더 편할 수도 있다. 예를 들자면
// Objective-C Example
CGFloat value = drand48() * 100;

// Swift Example
let value: Double = drand48() * 100
이렇게 하면 0에서 100 사이의 실수를 얻을 수 있다.

PS. arc4random() 및 arc4random 이름이 붙은 함수들은 별도의 씨드 설정이 필요없다. 그래서 일반적인 C 난수 발생 함수인 rand() 나 random() 보다 추천되는 함수다.

PS2. arc4random()류 함수는 스위프트에서는 UInt32 값으로 리턴된다. 이 값이 Int32 보다는 클 수도 있으므로 32비트 플랫폼을 대비한다면 그냥 UInt32 로 받아서 처리하자.

댓글 없음 :