0과 1 사이의 임의의 숫자를 생성하려고합니다.에 대해 계속 읽고 arc4random()
있지만 여기에서 부동 소수점을 얻는 방법에 대한 정보가 없습니다. 어떻게해야합니까?
답변:
ARC4RANDOM_MAX
수동으로 정의 해야하는 것은 이상 하지만 0x100000000
4294967296 입니다 ULONG_MAX + 1
. arc4random()
맥스가 ULONG_MAX
어떻게 든 문서화되어 있습니까?
// Seed (only once)
srand48(time(0));
double x = drand48();
// Swift version
// Seed (only once)
srand48(Int(Date().timeIntervalSince1970))
let x = drand48()
drand48 () 및 erand48 () 함수는 [0.0, 1.0] 간격에 균일하게 분포 된 음이 아닌 배정 밀도 부동 소수점 값을 반환합니다.
double
. 최고의 정밀도를 달성하는 방법 은 stackoverflow.com/a/34765674/1033581 을 참조하십시오 .
Swift 4.2 이상은 https://stackoverflow.com/a/50733095/1033581을 참조하십시오.
다음은 ObjC 및 Swift 4.1의 올바른 균일 성 및 최적 정밀도에 대한 권장 사항입니다.
Float
)[0, 1] (0.0 및 1.0 포함)의 균일 한 임의 값 , 최대 32 비트 정밀도 :
Obj-C :
float val = (float)arc4random() / UINT32_MAX;
스위프트 :
let val = Float(arc4random()) / Float(UInt32.max)
다음과 같은 경우에 최적입니다.
Float
(또는 Float32
)drand48
( 후드 아래 사용)를 사용 arc4random_buf
하면 48 비트 정밀도를 쉽게 얻을 수 있습니다. 그러나 drand48에는 시드 요구 사항 및 Double 가수의 모든 52 비트를 무작위 화하는 데 차선책이되기 때문에 결함이 있습니다.
[0, 1] , 48 비트 정밀도의 균일 한 임의 값 :
스위프트 :
// seed (only needed once)
srand48(Int(Date.timeIntervalSinceReferenceDate))
// random Double value
let val = drand48()
Double
및에 최적 Float80
)[0, 1] (0.0 및 1.0 포함)의 균일 한 임의 값 , 최대 64 비트 정밀도 :
arc4random에 대한 두 번의 호출을 사용하는 Swift :
let arc4random64 = UInt64(arc4random()) << 32 &+ UInt64(arc4random())
let val = Float80(arc4random64) / Float80(UInt64.max)
arc4random_buf에 대한 한 번의 호출을 사용하는 Swift :
var arc4random64: UInt64 = 0
arc4random_buf(&arc4random64, MemoryLayout.size(ofValue: arc4random64))
let val = Float80(arc4random64) / Float80(UInt64.max)
다음과 같은 경우에 최적입니다.
Double
(또는 Float64
)Float80
그 가수에 대한 64 비트의 유효 숫자 정밀도를 갖는범위가 경계 (0 또는 1) 중 하나를 제외하는 답변은 균일 성 편향이있을 수 있으므로 피해야합니다.
arc4random()
하면 최상의 정밀도는 1 / 0xFFFFFFFF (UINT32_MAX)입니다.arc4random_uniform()
하면 최상의 정밀도는 1 / 0xFFFFFFFE (UINT32_MAX-1)입니다.rand()
( 비밀리에 arc4random 사용 ), 최고의 정밀도는 1 / 0x7FFFFFFF (RAND_MAX)random()
( 비밀리에 arc4random 사용 ), 최고의 정밀도는 1 / 0x7FFFFFFF (RAND_MAX)그것은 단일 호출로보다 나은 32 비트 정밀도를 달성하기 위해 수학적으로 불가능하다 arc4random
, arc4random_uniform
, rand
또는 random
. 따라서 위의 32 비트 및 64 비트 솔루션은 우리가 달성 할 수있는 최선의 방법이어야합니다.
이 함수는 음수 부동 범위에서도 작동합니다.
float randomFloat(float Min, float Max){
return ((arc4random()%RAND_MAX)/(RAND_MAX*1.0))*(Max-Min)+Min;
}
Min+(Max-Min)*((float)arc4random())/ULONG_MAX
대신. (float)
캐스트는 편집증입니다.
Swift 4.2는 Range의 임의 값에 대한 기본 지원을 추가합니다.
let x = Float.random(in: 0.0...1.0)
let y = Double.random(in: 0.0...1.0)
let z = Float80.random(in: 0.0...1.0)
문서:
이것은 Float 난수 Swift 3.1의 확장입니다.
// MARK: Float Extension
public extension Float {
/// Returns a random floating point number between 0.0 and 1.0, inclusive.
public static var random: Float {
return Float(arc4random()) / Float(UInt32.max))
}
/// Random float between 0 and n-1.
///
/// - Parameter n: Interval max
/// - Returns: Returns a random float point number between 0 and n max
public static func random(min: Float, max: Float) -> Float {
return Float.random * (max - min) + min
}
}
스위프트 4.2
Swift 4.2는 표준 라이브러리에 기본적이고 완전한 기능을 갖춘 난수 API를 포함했습니다. ( Swift Evolution 제안 SE-0202 )
let intBetween0to9 = Int.random(in: 0...9)
let doubleBetween0to1 = Double.random(in: 0...1)
모든 숫자 유형에는 범위를 취하고 주어진 범위에서 임의의 숫자를 반환 하는 정적 random (in :) 함수가 있습니다.
arc4random () 의 상한 문제를 피하기 위해 이것을 사용하십시오.
u_int32_t upper_bound = 1000000;
float r = arc4random_uniform(upper_bound)*1.0/upper_bound;
MAC_10_7, IPHONE_4_3 이상에 적용됩니다.
upper_bound-1
. 그러나 upper_bound로 인해 정밀도가 임의로 낮으므로 upper_bound를 UINT32_MAX로 늘려야합니다. 그리고 당신이 사용하는 더 나은 정밀도를 얻을 수 있습니다 arc4random()*1.0 / UINT32_MAX
대신 arc4random_uniform(UINT32_MAX)*1.0 / (UINT32_MAX-1)
.
arc4random
범위는 최대 0x100000000 (4294967296)입니다.
이것은 0에서 1 사이의 난수를 생성하는 또 다른 좋은 옵션입니다.
srand48(time(0)); // pseudo-random number initializer.
double r = drand48();
float x = arc4random() % 11 * 0.1;
즉 0 bewteen 임의의 부동 소수점과 1 생산하고 여기에 더 많은 정보를
rand()
기본적으로 0과 1 사이의 난수 (float)를 생성합니다.
rand()
은 C의 일부이며 Objective-C (iOS 프로그래밍에 사용됨)의 일부입니다. rand()
iOS에는 절대적으로 존재하는 것과 같은 C 함수 arc4random()
가 있지만 선호됩니다.