0과 1 사이의 임의 부동 소수점 생성


84

0과 1 사이의 임의의 숫자를 생성하려고합니다.에 대해 계속 읽고 arc4random()있지만 여기에서 부동 소수점을 얻는 방법에 대한 정보가 없습니다. 어떻게해야합니까?


1
중복이 아니라, 이것은 명시 적으로 수레와 관련된 유일한 질문 인 것 같습니다.
P i

답변:


139

[0, 1 [의 임의 값 (0 포함 , 1 제외)) :

double val = ((double)arc4random() / UINT32_MAX);

여기에 좀 더 자세한 내용이 있습니다 .

상한은 (double) 0xFFFFFFFF / 0x100000000 이므로 실제 범위는 [0, 0.999999999767169356] 입니다.


감사합니다. 내가 본 가장 직접적인 대답. 나는 귀하의 링크를 읽고 이에 대한 추가 세부 사항을 얻을 것입니다. 다시 한 번 감사드립니다.
jini 2011 년

3
ARC4RANDOM_MAX수동으로 정의 해야하는 것은 이상 하지만 0x1000000004294967296 입니다 ULONG_MAX + 1. arc4random()맥스가 ULONG_MAX어떻게 든 문서화되어 있습니까?
bobobobo

@bobobobo, 여기에서 : developer.apple.com/library/mac/#documentation/Darwin/Reference/… arc4random () 함수는 0에서 (2 ** 32) -1 범위의 의사 난수를 반환합니다.
Vladimir

8
실제로 값은 0xFFFFFFFF, (2 ** 32) -1 == 0x100000000-0x1 == 0xFFFFFFFF == UINT32_MAX 여야합니다.
Josejulio

1
이러한 방식으로 생성 된 값은 균일하게 배포된다는 보장이 없습니다!
킬린

107
// 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] 간격에 균일하게 분포 된 음이 아닌 배정 밀도 부동 소수점 값을 반환합니다.


19
이것이 최선의 답이 될 것입니다.
John Riselvato 2013 년

답변을 약간 업데이트 해야 할 수도 있습니다. 시드로 한 번 초기화해야하는 NSHipster 에서 읽었습니다drand48 . 애플 문서는 또한 초기화되어야하는 것이 좋습니다.
dulaccc 2014 년

1
이 랜덤 생성기에 계산 시작점을 제공하기 때문에 Seed가 필요합니다. 그것 없이는 임의의 순서가 앱 실행 전체에서 항상 동일합니다.
Jovan Stankovic 2017

이것이 최선의 대답입니다.
sabiland

이 답변은에 대한 최적의 정밀도 답변이 아닙니다 double. 최고의 정밀도를 달성하는 방법 은 stackoverflow.com/a/34765674/1033581 을 참조하십시오 .
Cœur

16

Swift 4.2 이상은 https://stackoverflow.com/a/50733095/1033581을 참조하십시오.


다음은 ObjC 및 Swift 4.1의 올바른 균일 성 및 최적 정밀도에 대한 권장 사항입니다.

32 비트 정밀도 (에 최적 Float)

[0, 1] (0.0 및 1.0 포함)의 균일 한 임의 값 , 최대 32 비트 정밀도 :

Obj-C :

float val = (float)arc4random() / UINT32_MAX;

스위프트 :

let val = Float(arc4random()) / Float(UInt32.max)

다음과 같은 경우에 최적입니다.

  • 가수에 대해 유효 정밀도가 24 비트 인 a Float(또는 Float32)

48 비트 정밀도 (권장되지 않음)

drand48( 후드 아래 사용)를 사용 arc4random_buf하면 48 비트 정밀도를 쉽게 얻을 수 있습니다. 그러나 drand48에는 시드 요구 사항 및 Double 가수의 모든 52 비트를 무작위 화하는 데 차선책이되기 때문에 결함이 있습니다.

[0, 1] , 48 비트 정밀도의 균일 한 임의 값 :

스위프트 :

// seed (only needed once)
srand48(Int(Date.timeIntervalSinceReferenceDate))
// random Double value
let val = drand48()

64 비트 정밀도 ( 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)

다음과 같은 경우에 최적입니다.

  • 가수에 대해 유효 정밀도가 52 비트 인 a 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 비트 솔루션은 우리가 달성 할 수있는 최선의 방법이어야합니다.


'Float80'은 실제 iOS 기기에서 사용할 수 없습니다 (시뮬레이터에서만 작동).
Cœur

10

이 함수는 음수 부동 범위에서도 작동합니다.

float randomFloat(float Min, float Max){
    return ((arc4random()%RAND_MAX)/(RAND_MAX*1.0))*(Max-Min)+Min;
}

4
외부 계수 작동. 사용하는 Min+(Max-Min)*((float)arc4random())/ULONG_MAX대신. (float)캐스트는 편집증입니다.
bobobobo

@bobobobo 외계 계수에 동의하는 동안 ULONG_MAX (64 비트에서 18446744073709551615) 대신 UINT32_MAX (항상 4294967295)로 나누는 것이 좋습니다.
Cœur


1
(float)rand() / RAND_MAX

"rand ()"만 언급 한 이전 게시물은 잘못되었습니다. 이것은 rand ()를 사용하는 올바른 방법입니다.

0-> 1 사이의 숫자가 생성됩니다.

BSD 문서 :

rand () 함수
는 0에서 RAND_MAX (헤더 파일 "stdlib.h"에 정의 된대로) 범위 의 의사 난수 정수 시퀀스를 계산합니다 .


1

이것은 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
    }
}

쾨르 감사 @ 당신은 내가 그 변경
YannSteph

1

스위프트 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 :) 함수가 있습니다.


0

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를 10으로 설정하면 쉽게 눈에 띄고 arc4random_uniform은 0에서 9까지의 값을 반환하고 최종 결과는 0.0000에서 0.9000까지입니다. 대신 upper_bound-1. 그러나 upper_bound로 인해 정밀도가 임의로 낮으므로 upper_bound를 UINT32_MAX로 늘려야합니다. 그리고 당신이 사용하는 더 나은 정밀도를 얻을 수 있습니다 arc4random()*1.0 / UINT32_MAX대신 arc4random_uniform(UINT32_MAX)*1.0 / (UINT32_MAX-1).
Cœur

-1

arc4random 범위는 최대 0x100000000 (4294967296)입니다.

이것은 0에서 1 사이의 난수를 생성하는 또 다른 좋은 옵션입니다.

srand48(time(0));      // pseudo-random number initializer.
double r = drand48();

arc4random 최대 값은 0xFFFFFFFF
Cœur

감사합니다 @ 쾨르 ..max 발을 0xFFFFFFFF 내가 모르는 한
Gurunatha 도기

귀하의 솔루션은 Jovan Stankovic 답변과 동일합니다.
Cœur

오 내가보고하지 않았다 쾨르 @
Gurunatha 도기

-4
float x = arc4random() % 11 * 0.1;

즉 0 bewteen 임의의 부동 소수점과 1 생산하고 여기에 더 많은 정보를


3
참고 : 0.0, 0.1, 0.2, ..., 1.0의 개별 값 11 개만 제공
TalkLittle

8
예, 모듈러스 연산은 arc4random ()의 결과를 0에서 10 사이로 잘라낸 다음 10으로 나눕니다.이 대답은 일반적으로 사용하기에 정말 좋지 않습니다.
bobobobo 2012

-4
rand() 

기본적으로 0과 1 사이의 난수 (float)를 생성합니다.


4
이것은 나를 위해 임의의 int를 생성합니다.
AlexQueue

rand()iOS에 존재 하지 않는 것 같고, 존재 한다면 다른 모든 * NIX 에서처럼 정수를 생성합니다.
jscs 2013-04-22

2
@JoshCaswell rand()은 C의 일부이며 Objective-C (iOS 프로그래밍에 사용됨)의 일부입니다. rand()iOS에는 절대적으로 존재하는 것과 같은 C 함수 arc4random()가 있지만 선호됩니다.
Frungi 2011
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.