Ich versuche , eine Zufallszahl zu erzeugen, ist zwischen 0 und 1. Ich halte das Lesen über arc4random()
, aber es gibt keine Informationen über einen Schwimmer von ihm zu bekommen. Wie mache ich das?
Ich versuche , eine Zufallszahl zu erzeugen, ist zwischen 0 und 1. Ich halte das Lesen über arc4random()
, aber es gibt keine Informationen über einen Schwimmer von ihm zu bekommen. Wie mache ich das?
Antworten:
Zufälliger Wert in [0, 1 [ (einschließlich 0, ohne 1):
double val = ((double)arc4random() / UINT32_MAX);
Ein bisschen mehr Details hier .
Der tatsächliche Bereich ist [0, 0,999999999767169356] , da die Obergrenze (doppelt) 0xFFFFFFFF / 0x100000000 ist.
ARC4RANDOM_MAX
manuell definiert werden, sondern 0x100000000
ist 4294967296 , was ist ULONG_MAX + 1
. Wo ist dokumentiert, dass arc4random()
das Maximum ULONG_MAX
sowieso ist?
// Seed (only once)
srand48(time(0));
double x = drand48();
// Swift version
// Seed (only once)
srand48(Int(Date().timeIntervalSince1970))
let x = drand48()
Die Funktionen drand48 () und erand48 () geben nicht negative Gleitkommawerte mit doppelter Genauigkeit zurück, die gleichmäßig über das Intervall verteilt sind [0.0, 1.0].
drand48
müssen Sie die Antwort nur ein wenig aktualisieren. Ich habe auf NSHipster gelesen , dass sie einmal mit einem Startwert initialisiert werden muss. Die Apple-Dokumentation schlägt außerdem vor, dass es initialisiert werden sollte.
double
. Informationen zum Erreichen der besten Präzision finden Sie unter stackoverflow.com/a/34765674/1033581 .
Swift 4.2+ finden Sie unter: https://stackoverflow.com/a/50733095/1033581
Nachfolgend finden Sie Empfehlungen zur korrekten Gleichmäßigkeit und optimalen Präzision für ObjC und Swift 4.1.
Float
)Einheitlicher Zufallswert in [0, 1] (einschließlich 0.0 und 1.0) mit einer Genauigkeit von bis zu 32 Bit:
Obj-C :
float val = (float)arc4random() / UINT32_MAX;
Swift :
let val = Float(arc4random()) / Float(UInt32.max)
Es ist optimal für:
Float
(oder Float32
) mit einer signifikanten Genauigkeit von 24 Bit für seine MantisseEs ist einfach, eine Genauigkeit von 48 Bit zu erreichen drand48
( die arc4random_buf
unter der Haube verwendet wird ). Aber beachte das drand48 aufgrund der Seed-Anforderung und auch aufgrund der suboptimalen Zufallsgenerierung aller 52 Bits der Doppelmantisse Fehler aufweist .
Einheitlicher Zufallswert in [0, 1] , 48 Bit Genauigkeit:
Swift :
// seed (only needed once)
srand48(Int(Date.timeIntervalSinceReferenceDate))
// random Double value
let val = drand48()
Double
undFloat80
)Einheitlicher Zufallswert in [0, 1] (einschließlich 0.0 und 1.0) mit einer Genauigkeit von bis zu 64 Bit:
Swift verwendet zwei Aufrufe von arc4random:
let arc4random64 = UInt64(arc4random()) << 32 &+ UInt64(arc4random())
let val = Float80(arc4random64) / Float80(UInt64.max)
Swift mit einem Aufruf von arc4random_buf:
var arc4random64: UInt64 = 0
arc4random_buf(&arc4random64, MemoryLayout.size(ofValue: arc4random64))
let val = Float80(arc4random64) / Float80(UInt64.max)
Es ist optimal für:
Double
(oderFloat64
) mit einer signifikanten Genauigkeit von 52 Bit für seine MantisseFloat80
mit einer signifikanten Genauigkeit von 64 Bit für seine MantisseAntworten, bei denen der Bereich eine der Grenzen (0 oder 1) ausschließt, leiden wahrscheinlich unter einer Gleichmäßigkeitsverzerrung und sollten vermieden werden.
arc4random()
ist die beste Genauigkeit 1 / 0xFFFFFFFF (UINT32_MAX)arc4random_uniform()
ist die beste Genauigkeit 1 / 0xFFFFFFFE (UINT32_MAX-1)rand()
( heimlich mit arc4random ) ist die beste Genauigkeit 1 / 0x7FFFFFFF (RAND_MAX).random()
( heimlich mit arc4random ) ist die beste Genauigkeit 1 / 0x7FFFFFFF (RAND_MAX).Es ist mathematisch unmöglich besser als 32 - Bit - Präzision mit einem einzigen Anruf zu erzielen arc4random
, arc4random_uniform
, rand
oder random
. Daher sollten unsere über 32-Bit- und 64-Bit-Lösungen die besten sein, die wir erreichen können.
Diese Funktion funktioniert auch für negative Float-Bereiche:
float randomFloat(float Min, float Max){
return ((arc4random()%RAND_MAX)/(RAND_MAX*1.0))*(Max-Min)+Min;
}
Min+(Max-Min)*((float)arc4random())/ULONG_MAX
stattdessen. Die (float)
Besetzung ist nur Paranoia.
Swift 4.2 bietet native Unterstützung für einen zufälligen Wert in einem Bereich:
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)
Doc:
(float)rand() / RAND_MAX
Der vorherige Beitrag mit der Angabe "rand ()" war falsch. Dies ist der richtige Weg, um rand () zu verwenden.
Dadurch wird eine Zahl zwischen 0 -> 1 erstellt
BSD-Dokumente:
Die Funktion rand () berechnet eine Folge von pseudozufälligen ganzen Zahlen im
Bereich von 0 bis RAND_MAX (wie in der Header-Datei "stdlib.h" definiert).
Dies ist eine Erweiterung für die Float-Zufallszahl 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
}
}
Swift 4.2
Swift 4.2 hat eine native und ziemlich voll funktionsfähige Zufallszahlen-API in die Standardbibliothek aufgenommen. ( Swift Evolution Vorschlag SE-0202 )
let intBetween0to9 = Int.random(in: 0...9)
let doubleBetween0to1 = Double.random(in: 0...1)
Alle Zahlentypen haben die statische Zufallsfunktion (in :) , die den Bereich übernimmt und die Zufallszahl im angegebenen Bereich zurückgibt.
Verwenden Sie diese Option , um Probleme mit der Obergrenze von arc4random () zu vermeiden.
u_int32_t upper_bound = 1000000;
float r = arc4random_uniform(upper_bound)*1.0/upper_bound;
Beachten Sie, dass dies für MAC_10_7, IPHONE_4_3 und höher gilt.
upper_bound-1
. Sie hätten jedoch immer noch eine willkürlich niedrige Genauigkeit, die durch Upper_bound verursacht wird. Daher sollten Sie die Upper_bound auf UINT32_MAX erhöhen. Und Sie können noch präziser arbeiten, wenn Sie arc4random()*1.0 / UINT32_MAX
statt verwenden arc4random_uniform(UINT32_MAX)*1.0 / (UINT32_MAX-1)
.
Wie wäre es mit dieser Operation ((CGFloat)(rand()%100)/100)
?
arc4random
hat einen Bereich bis 0x100000000 (4294967296)
Dies ist eine weitere gute Option, um Zufallszahlen zwischen 0 und 1 zu generieren:
srand48(time(0)); // pseudo-random number initializer.
double r = drand48();
float x = arc4random() % 11 * 0.1;
Das ergibt einen zufälligen Float zwischen 0 und 1. Mehr Infos hier
rand()
Standardmäßig wird eine Zufallszahl (float) zwischen 0 und 1 erzeugt.
rand()
scheint unter iOS nicht zu existieren , und wenn dies der Fall wäre, würde es eine Ganzzahl erzeugen, wie es bei jedem anderen * NIX der Fall ist.
rand()
ist Teil von C, das wiederum Teil von Objective-C ist (das in der iOS-Programmierung verwendet wird). C-Funktionen wie rand()
auf iOS existieren absolut, werden aber arc4random()
bevorzugt.