답변:
이 arc4random_uniform()
기능을 사용해야합니다 . 에 우수한 알고리즘을 사용합니다 rand
. 씨앗을 설정할 필요조차 없습니다.
#include <stdlib.h>
// ...
// ...
int r = arc4random_uniform(74);
arc4random
매뉴얼 페이지
NAME arc4random, arc4random_stir, arc4random_addrandom -- arc4 random number generator LIBRARY Standard C Library (libc, -lc) SYNOPSIS #include <stdlib.h> u_int32_t arc4random(void); void arc4random_stir(void); void arc4random_addrandom(unsigned char *dat, int datlen); DESCRIPTION The arc4random() function uses the key stream generator employed by the arc4 cipher, which uses 8*8 8 bit S-Boxes. The S-Boxes can be in about (2**1700) states. The arc4random() function returns pseudo- random numbers in the range of 0 to (2**32)-1, and therefore has twice the range of rand(3) and random(3). The arc4random_stir() function reads data from /dev/urandom and uses it to permute the S-Boxes via arc4random_addrandom(). There is no need to call arc4random_stir() before using arc4random(), since arc4random() automatically initializes itself. EXAMPLES The following produces a drop-in replacement for the traditional rand() and random() functions using arc4random(): #define foo4random() (arc4random() % ((unsigned)RAND_MAX + 1))
arc4random_uniform(upper_bound)
함수를 사용하여 범위 내에서 난수를 생성 하십시오 . 다음은 0에서 73 사이의 숫자를 생성합니다.
arc4random_uniform(74)
arc4random_uniform(upper_bound)
매뉴얼 페이지에 설명 된대로 모듈로 바이어스 를 방지 합니다.
arc4random_uniform ()은 upper_bound보다 작은 균일하게 분포 된 난수를 반환합니다. arc4random_uniform ()은``arc4random () % upper_bound ''와 같은 구성보다 권장 됩니다. 상한이 2의 거듭 제곱이 아닌 경우 " 모듈러스 바이어스 "를 피하기 때문입니다.
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_4_3
실패하면 다른 솔루션으로 넘어갑니다.
C와 똑같이
#include <time.h>
#include <stdlib.h>
...
srand(time(NULL));
int r = rand() % 74;
(0을 포함하지만 74는 제외한다고 가정하면 Java 예제와 동일합니다)
편집 : Feel로 대체 할 무료 random()
나 arc4random()
에 대한 rand()
(다른 사람들이 지적으로,이다, 매우 짜증나).
많은 프로젝트에서 사용하는 방법을 추가 할 수 있다고 생각했습니다.
- (NSInteger)randomValueBetween:(NSInteger)min and:(NSInteger)max {
return (NSInteger)(min + arc4random_uniform(max - min + 1));
}
많은 파일에서 사용하면 일반적으로 매크로를 다음과 같이 선언합니다.
#define RAND_FROM_TO(min, max) (min + arc4random_uniform(max - min + 1))
예 :
NSInteger myInteger = RAND_FROM_TO(0, 74) // 0, 1, 2,..., 73, 74
참고 : iOS 4.3 / OS X v10.7 (Lion) 이상에만 해당
이것은 0에서 47 사이 의 부동 소수점 숫자를 제공합니다
float low_bound = 0;
float high_bound = 47;
float rndValue = (((float)arc4random()/0x100000000)*(high_bound-low_bound)+low_bound);
아니면 그냥
float rndValue = (((float)arc4random()/0x100000000)*47);
하한과 상한도 모두 음수 일 수 있습니다 . 아래 예제 코드는 -35.76과 +12.09 사이의 난수를 제공합니다.
float low_bound = -35.76;
float high_bound = 12.09;
float rndValue = (((float)arc4random()/0x100000000)*(high_bound-low_bound)+low_bound);
결과를 더 둥근 정수 값으로 변환하십시오 .
int intRndValue = (int)(rndValue + 0.5);
drand48
부동 소수점에 대신 사용하십시오 .
rand (3) 매뉴얼 페이지에 따르면 rand 함수 계열은 random (3)에 의해 폐기되었습니다. 이는 rand ()의 하위 12 비트가 주기적 패턴을 거치기 때문입니다. 난수를 얻으려면 부호없는 시드로 srandom ()을 호출 한 다음 random ()을 호출하여 생성기를 시드하십시오. 따라서 위 코드와 동등한 것은
#import <stdlib.h>
#import <time.h>
srandom(time(NULL));
random() % 74;
시드를 변경하지 않는 한 프로그램에서 srandom ()을 한 번만 호출하면됩니다. 당신이 정말로 임의의 값에 대한 토론을 원하지 않는다고 말했지만, rand ()는 꽤 나쁜 난수 생성기이며 random ()은 여전히 0에서 RAND_MAX 사이의 숫자를 생성하기 때문에 모듈로 바이어스로 고통받습니다. 예를 들어, RAND_MAX가 3이고 0과 2 사이의 임의의 숫자를 원하는 경우 1 또는 2보다 0을 얻을 가능성이 두 배입니다.
사용하는 것이 좋습니다 arc4random_uniform
. 그러나 iOS 4.3 이하에서는 사용할 수 없습니다. 운 좋게 iOS는 컴파일 타임이 아닌 런타임에이 심볼을 바인딩합니다 (따라서 #if 프리 프로세서 지시문을 사용하여 사용 가능한지 확인하지 마십시오).
arc4random_uniform
사용 가능한지 확인하는 가장 좋은 방법 은 다음과 같은 작업을 수행하는 것입니다.
#include <stdlib.h>
int r = 0;
if (arc4random_uniform != NULL)
r = arc4random_uniform (74);
else
r = (arc4random() % 74);
Java에서 Math.random ()과 같은 기능을 수행 할 수 있도록 난수 유틸리티 클래스를 작성했습니다. 그것은 두 가지 기능을 가지고 있으며 모두 C로 만들어졌습니다.
헤더 파일 :
//Random.h
void initRandomSeed(long firstSeed);
float nextRandomFloat();
구현 파일 :
//Random.m
static unsigned long seed;
void initRandomSeed(long firstSeed)
{
seed = firstSeed;
}
float nextRandomFloat()
{
return (((seed= 1664525*seed + 1013904223)>>16) / (float)0x10000);
}
의사 난수를 생성하는 매우 고전적인 방법입니다. 내 앱 대리자에게 전화 :
#import "Random.h"
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
initRandomSeed( (long) [[NSDate date] timeIntervalSince1970] );
//Do other initialization junk.
}
그런 다음 나중에 그냥 말합니다.
float myRandomNumber = nextRandomFloat() * 74;
이 메소드는 0.0f (포함)와 1.0f (제외) 사이의 난수를 리턴합니다.
iOS 9 및 OS X 10.11부터 새로운 GameplayKit 클래스를 사용하여 다양한 방법으로 난수를 생성 할 수 있습니다.
선택할 수있는 네 가지 소스 유형이 있습니다 : 일반 무작위 소스 (이름이없는 시스템, 그 아래에있는 것을 선택하는 시스템), 선형 합동, ARC4 및 Mersenne Twister. 이들은 임의의 정수, 부동 소수점 및 부울을 생성 할 수 있습니다.
가장 간단한 수준에서 다음과 같이 시스템의 내장 임의 소스에서 난수를 생성 할 수 있습니다.
NSInteger rand = [[GKRandomSource sharedRandom] nextInt];
이는 -2,147,483,648과 2,147,483,647 사이의 숫자를 생성합니다. 0과 상한 (제외) 사이의 숫자를 원하면 다음을 사용하십시오.
NSInteger rand6 = [[GKRandomSource sharedRandom] nextIntWithUpperBound:6];
GameplayKit에는 주사위와 함께 사용할 수있는 편리한 생성자가 있습니다. 예를 들어 다음과 같이 6 면체 주사위를 굴릴 수 있습니다.
GKRandomDistribution *d6 = [GKRandomDistribution d6];
[d6 nextInt];
또한와 같은 것을 사용하여 랜덤 분포를 형성 할 수 있습니다 GKShuffledDistribution
.
게임 개발자의 경우 random ()을 사용하여 무작위를 생성하십시오. 아마도 arc4random ()을 사용하는 것보다 적어도 5 배 빠릅니다. 모듈러스 바이어스는 전 범위의 random ()을 사용하여 랜덤을 생성 할 때 특히 게임에서 문제가되지 않습니다. 먼저 씨를 뿌려야합니다. AppDelegate에서 srandomdev ()를 호출하십시오. 다음은 몇 가지 도우미 기능입니다.
static inline int random_range(int low, int high){ return (random()%(high-low+1))+low;}
static inline CGFloat frandom(){ return (CGFloat)random()/UINT32_C(0x7FFFFFFF);}
static inline CGFloat frandom_range(CGFloat low, CGFloat high){ return (high-low)*frandom()+low;}
arc4random_uniform(x)
@yood에 의해 아래 설명 된대로 사용하십시오 . 또한 stdlib.h (OS X 10.7 및 iOS 4.3 이후)에 있으며 난수의보다 균일 한 분포를 제공합니다. 사용법int r = arc4random_uniform(74);