0 और 1 के बीच एक यादृच्छिक फ्लोट उत्पन्न करें


84

मैं एक यादृच्छिक संख्या उत्पन्न करने की कोशिश कर रहा हूं, जो 0 और 1 के बीच है। मैं इसके बारे में पढ़ता रहता हूं arc4random(), लेकिन इससे फ्लोट प्राप्त करने के बारे में कोई जानकारी नहीं है। मैं यह कैसे करु?


1
डुप्लिकेट नहीं, यह केवल एक सवाल है जो स्पष्ट रूप से फ्लोट्स से संबंधित है।
P i

जवाबों:


139

[0, 1] में यादृच्छिक मूल्य (0 को छोड़कर, 1 को छोड़कर):

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

यहाँ थोड़ा और विवरण ।

वास्तविक सीमा [0, 0.999999999767169356] है , क्योंकि ऊपरी सीमा (डबल) 0xFFFFFFFF / 0x100000000 है।


धन्यवाद। सबसे सीधे आगे का जवाब मैंने देखा है। मैं आपके लिंक पर पढ़ूंगा और इस पर अतिरिक्त विवरण प्राप्त करूंगा। एक बार फिर धन्यवाद।
जिनी

3
यह अजीब है जिसे ARC4RANDOM_MAXमैन्युअल रूप से परिभाषित किया जाना है, लेकिन 0x1000000004294967296 है , जो है ULONG_MAX + 1। यह कहाँ प्रलेखित है कि किसी भी तरह arc4random()अधिकतम है ULONG_MAX?
बोबोबो

@bobobobo, यहां से: developer.apple.com/library/mac/#documentation/Darwin/Reference/… The arc4random () फ़ंक्शन 0 से (2 ** 32) -1 की सीमा में छद्म यादृच्छिक संख्या देता है
व्लादिमीर

8
दरअसल, मान 0xFFFFFFFF, (2 ** 32) -1 == 0x100000000 - 0x1 == 0xFFFFFFFF == UINT32_MAX जैसा कि वर्तमान में लिंक पर Jörg Bümanmann द्वारा कहा गया है।
जोसजुलियो

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
यह सबसे अच्छा जवाब होना चाहिए।
जॉन रिसेल्वेटो

आपको शायद बस थोड़ा सा जवाब अपडेट करने की जरूरत है, मैं NSHipster पर पढ़ता हूं जिसे drand48एक बार एक बीज के साथ आरंभ करने की आवश्यकता है। एप्पल प्रलेखन भी सुझाव है कि यह प्रारंभ किया जाना चाहिए।
dulaccc

1
बीज की आवश्यकता है क्योंकि यह इस यादृच्छिक जनरेटर को गणना के लिए एक प्रारंभिक बिंदु देता है। इसके बिना रैंडम सीक्वेंस हमेशा ऐप लॉन्च के दौरान समान रहेगा।
जोवान स्टेनकोविक 13

यह सबसे अच्छा जवाब है।
सबीलैंड

यह उत्तर एक के लिए एक इष्टतम सटीक उत्तर नहीं है double। सबसे अच्छी परिशुद्धता कैसे प्राप्त करें, इस पर stackoverflow.com/a/34765674/1033581 देखें ।
कूर

16

स्विफ्ट के लिए 4.2+ देखें: https://stackoverflow.com/a/50733095/1033581


नीचे ओजेसी और स्विफ्ट 4.1 के लिए सही एकरूपता और इष्टतम परिशुद्धता के लिए सिफारिशें दी गई हैं।

32 बिट्स सटीक (के लिए इष्टतम Float)

[०, १] (०.० और १.० सहित) में एकसमान यादृच्छिक मान , ३२ बिट तक सटीक:

ओबज-सी :

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

स्विफ्ट :

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

यह इसके लिए इष्टतम है:

  • a Float(या Float32) जिसके मंटिसा के लिए 24 बिट्स की एक महत्वपूर्ण परिशुद्धता है

48 बिट्स सटीक (हतोत्साहित)

48 बिट्स को सटीक रूप से प्राप्त करना आसान है drand48( जो arc4random_bufहुड के नीचे उपयोग करता है )। लेकिन ध्यान दें कि drand48 में बीज की आवश्यकता के कारण खामियां हैं और सब मोंटिसा के सभी 52 बिट्स को बेतरतीब करने के लिए उप- रूपी होने के लिए भी।

[०, १] , ४ 0 बिट्स सटीकता में समान यादृच्छिक मान :

स्विफ्ट :

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

64 बिट्स सटीक (के लिए इष्टतम Doubleऔर Float80)

[०, १] (०.० और १.० सहित) में एकसमान यादृच्छिक मान , ६४ बिट्स तक सटीक:

स्विफ्ट , आर्क 4 आयामी के लिए दो कॉल का उपयोग कर:

let arc4random64 = UInt64(arc4random()) << 32 &+ UInt64(arc4random())
let val = Float80(arc4random64) / Float80(UInt64.max)

एक कॉल का उपयोग करके स्विफ्ट करें , arc4random_buf:

var arc4random64: UInt64 = 0
arc4random_buf(&arc4random64, MemoryLayout.size(ofValue: arc4random64))
let val = Float80(arc4random64) / Float80(UInt64.max)

यह इसके लिए इष्टतम है:

  • a Double(या Float64) जिसके मंटिसा के लिए 52 बिट्स की एक महत्वपूर्ण परिशुद्धता है
  • एक Float80अपने अपूर्णांश के लिए 64 बिट्स की एक significand सटीक है जो

टिप्पणियाँ

अन्य तरीकों से तुलना

उत्तर जहां सीमा एक सीमा को छोड़ रही है (0 या 1) संभावना एकरूपता पूर्वाग्रह से ग्रस्त है और इसे टाला जाना चाहिए।

यह गणितीय रूप से असंभव है कि एक कॉल के साथ , या arc4random, 32 बिट परिशुद्धता से बेहतर प्राप्त किया जा सके । तो हमारे ऊपर 32 बिट्स और 64 बिट्स समाधान सबसे अच्छा होना चाहिए जिसे हम प्राप्त कर सकते हैं।arc4random_uniformrandrandom


'फ्लोट 80' असली आईओएस डिवाइस पर उपलब्ध नहीं है (यह केवल सिम्युलेटर पर काम करता है)।
कॉर

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 जब मैं बाहरी मापांक पर सहमत होता हूं, तो मैं ULONG_MAX (6444 बिट्स पर 18446744073709551615) के बजाय UINT32_MAX (4294967295 हमेशा) से विभाजित करने की सलाह देता हूं।
करूर

7

स्विफ्ट 4.2+

Swift 4.2 एक श्रेणी में यादृच्छिक मान के लिए मूल समर्थन जोड़ता है:

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)

डॉक्टर:


1
(float)rand() / RAND_MAX

अकेले "रैंड ()" बताते हुए पिछला पोस्ट गलत था। यह रैंड () का उपयोग करने का सही तरीका है।

यह 0 -> 1 के बीच एक नंबर बनाएगा

बीएसडी डॉक्स:

रैंड () फ़ंक्शन
0 से RAND_MAX की सीमा में छद्म-यादृच्छिक पूर्णांकों के अनुक्रम की गणना करता है (जैसा कि हेडर फ़ाइल "stdlib.h" द्वारा परिभाषित किया गया है)।


1

यह फ्लोट यादृच्छिक संख्या स्विफ्ट 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
    }
}

@
C @ur

1

स्विफ्ट 4.2

स्विफ्ट 4.2 ने मानक पुस्तकालय में एक देशी और काफी पूर्ण-यादृच्छिक रैंडम नंबर एपीआई को शामिल किया है। ( स्विफ्ट इवोल्यूशन प्रस्ताव SE-0202 )

let intBetween0to9 = Int.random(in: 0...9) 
let doubleBetween0to1 = Double.random(in: 0...1)

सभी संख्या प्रकारों में स्थिर रैंडम (इन :) फ़ंक्शन होता है जो रेंज लेता है और दिए गए रेंज में रैंडम नंबर देता है।


0

चाप 4random के ऊपरी सीमा के साथ समस्याओं से बचने के लिए इसका उपयोग करें ()

u_int32_t upper_bound = 1000000;

float r = arc4random_uniform(upper_bound)*1.0/upper_bound;

ध्यान दें कि यह MAC_10_7, IPHONE_4_3 और उच्चतर के लिए लागू है।


इसके साथ एक मूलभूत श्रेणी का मुद्दा है। जब आप 10 से ऊपरी सेट करते हैं तो यह आसानी से ध्यान देने योग्य होता है, arc4random_uniform 0 से 9 तक मान लौटाएगा, और अंतिम परिणाम 0.0000 से 0.9000 तक होगा। आपको इसके बजाय विभाजित करना चाहिए upper_bound-1। फिर भी, आपके पास अभी भी ऊपरी तौर पर अपर_बाउंड की वजह से कम सटीकता है, इसलिए आपको ऊपरी_उंटर को UINT32MMAX तक बढ़ाना चाहिए। और आप arc4random()*1.0 / UINT32_MAXइसके बजाय उपयोग करने से बेहतर परिशुद्धता प्राप्त कर सकते हैं arc4random_uniform(UINT32_MAX)*1.0 / (UINT32_MAX-1)
सेर

-1

arc4random 0x100000000 (4294967296) तक की सीमा होती है

0 से 1 के बीच यादृच्छिक संख्या उत्पन्न करने के लिए यह एक और अच्छा विकल्प है:

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

arc4random अधिकतम मान पर 0xFFFFFFFF है
कोयूर

धन्यवाद @ CFFur ..max वैल 0xFFFFFFFF मुझे पता नहीं था
गुरूनाथ डॉगी

आपका समाधान जोवन स्टैंकोविक जवाब के समान है।
सेर

ओह, मैंने यह नहीं देखा कि @ कूर
गुरूनाथ डॉगी

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

यह एक बेतरतीब नाव का निर्माण करता है 0 और 1. यहाँ अधिक जानकारी


3
नोट: केवल 11 असतत मान देता है: 0.0, 0.1, 0.2, ..., 1.0
TalkLittle

8
हां, मापांक ऑपरेशन आर्क 4 आयामी () के परिणाम को 0 से 10 के बीच रखता है, फिर वह इसे 10. से विभाजित करता है। यह उत्तर सामान्य उपयोग के लिए वास्तव में खराब है।
बोबोबो

-4
rand() 

डिफ़ॉल्ट रूप से 0 और 1 के बीच एक यादृच्छिक संख्या (फ्लोट) का उत्पादन करता है।


4
यह मेरे लिए एक यादृच्छिक int पैदा करता है।
एलेक्सक्यूयू

rand()आईओएस पर मौजूद नहीं लगता है , और अगर ऐसा होता है, तो यह एक पूर्णांक का उत्पादन करेगा जैसे यह हर दूसरे * NIX पर करता है।
jscs

2
@ जोशसवेल rand()सी का हिस्सा है, जो ऑब्जेक्टिव-सी (जो आईओएस प्रोग्रामिंग में उपयोग किया जाता है) के बदले हिस्से में है। सी जैसे कार्य rand()आईओएस पर पूरी तरह से मौजूद हैं, लेकिन arc4random()इसे प्राथमिकता दी जाती है।
फ्रूंगी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.