Generieren Sie einen zufälligen Float zwischen 0 und 1

Lesezeit: 5 Minuten

Benutzeravatar von jini
Jini

Ich versuche, eine Zufallszahl zu generieren, die zwischen 0 und 1 liegt. Ich lese weiter arc4random(), aber es gibt keine Informationen darüber, wie man einen Schwimmer daraus bekommt. Wie mache ich das?

  • Keine Duplikate, dies scheint die einzige Frage zu sein, die sich ausdrücklich auf Floats bezieht.

    – P ich

    29. Mai 2011 um 8:56 Uhr

Benutzeravatar von Vladimir
Wladimir

Zufallswert ein [0, 1[ (including 0, excluding 1):

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

A bit more details here.

Actual range is [0, 0.999999999767169356]als Obergrenze ist (double)0xFFFFFFFF / 0x100000000.

  • Danke. Die direkteste Antwort, die ich gesehen habe. Ich werde mir Ihren Link durchlesen und weitere Details dazu erhalten. Danke noch einmal.

    – Jini

    2. März 2011 um 19:40 Uhr

  • Das ist seltsam ARC4RANDOM_MAX muss manuell definiert werden, aber 0x100000000 ist 4294967296welches ist ULONG_MAX + 1. Wo ist das dokumentiert arc4random()‘s Maximum ist ULONG_MAX jedenfalls?

    – bobobobo

    15. September 2012 um 16:53 Uhr


  • @bobobobo, von hier: developer.apple.com/library/mac/#documentation/Darwin/Reference/… Die Funktion arc4random() gibt Pseudozufallszahlen im Bereich von 0 bis (2**32)-1 zurück

    – Wladimir

    15. September 2012 um 17:18 Uhr

  • Eigentlich müsste der Wert 0xFFFFFFFF, (2**32)-1 == 0x100000000 – 0x1 == 0xFFFFFFFF == UINT32_MAX lauten wie aktuell von Jörg Bühmann auf dem Link angegeben.

    – Josejulio

    10. Dezember 2014 um 16:51 Uhr


  • Die so generierten Werte sind nicht garantiert gleichmäßig verteilt!

    – kelin

    9. Juni 2015 um 8:05 Uhr

Benutzeravatar von Jovan Stankovic
Jovan Stanković

// 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 Fließkommawerte mit doppelter Genauigkeit zurück, die gleichmäßig über das Intervall verteilt sind [0.0 , 1.0].

  • Dies sollte die beste Antwort sein.

    – Johannes Riselvato

    22. August 2013 um 14:00 Uhr

  • Vielleicht müssen Sie die Antwort nur ein wenig aktualisieren, ich Lesen Sie auf NSHipster das drand48 einmalig mit einem Seed initialisiert werden. Das Apple-Dokumentation schlagen auch vor, dass es initialisiert werden sollte.

    – dulaccc

    2. September 2014 um 13:39 Uhr


  • Seed wird benötigt, weil es diesem Zufallsgenerator einen Ausgangspunkt für Berechnungen gibt. Ohne sie wäre die zufällige Sequenz bei App-Starts immer gleich.

    – Jovan Stankovic

    4. Februar 2017 um 13:52 Uhr

  • Dies ist die beste Antwort.

    – sabiland

    26. Mai 2017 um 10:42 Uhr

  • Diese Antwort ist keine optimale Präzisionsantwort für a double. Unter stackoverflow.com/a/34765674/1033581 erfahren Sie, wie Sie die beste Präzision erreichen.

    – Coeur

    21. März 2018 um 1:31 Uhr

Benutzeravatar von Cœur
Coeur

Für Swift 4.2+ siehe: https://stackoverflow.com/a/50733095/1033581


Nachfolgend finden Sie Empfehlungen für die korrekte Einheitlichkeit und optimale Präzision für ObjC und Swift 4.1.

32-Bit-Präzision (Optimal für Float)

Einheitlicher Zufallswert in [0, 1] (einschließlich 0.0 und 1.0), bis zu 32 Bit Genauigkeit:

Objekt-C:

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

Schnell:

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

Es ist optimal für:

  • a Float (oder Float32), die eine signifikante Genauigkeit von 24 Bit für ihre Mantisse hat

48-Bit-Präzision (nicht empfohlen)

Es ist einfach, eine Genauigkeit von 48 Bit zu erreichen drand48 (was nutzt arc4random_buf unter der Haube). Aber beachte das drand48 hat Mängel wegen der Seed-Anforderung und auch, weil es suboptimal ist, alle 52 Bits der doppelten Mantisse zu randomisieren.

Einheitlicher Zufallswert in [0, 1]48-Bit-Präzision:

Schnell:

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

64-Bit-Präzision (Optimal für Double und Float80)

Einheitlicher Zufallswert in [0, 1] (einschließlich 0.0 und 1.0), bis zu 64 Bit Genauigkeit:

Schnellmit zwei Aufrufen von arc4random:

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

Schnellmit 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:

  • a Double (oder Float64), die eine signifikante Genauigkeit von 52 Bit für ihre Mantisse hat
  • a Float80 die eine signifikante Genauigkeit von 64 Bit für ihre Mantisse hat

Anmerkungen

Vergleiche mit anderen Methoden

Antworten, bei denen der Bereich eine der Grenzen (0 oder 1) ausschließt, leiden wahrscheinlich unter einer Verzerrung der Einheitlichkeit und sollten vermieden werden.

  • verwenden arc4random()beste Genauigkeit ist 1 / 0xFFFFFFFF (UINT32_MAX)
  • verwenden arc4random_uniform()beste Genauigkeit ist 1 / 0xFFFFFFFE (UINT32_MAX-1)
  • verwenden rand() (heimlich mit arc4random), beste Genauigkeit ist 1 / 0x7FFFFFFF (RAND_MAX)
  • verwenden random() (heimlich mit arc4random), beste Genauigkeit ist 1 / 0x7FFFFFFF (RAND_MAX)

Es ist mathematisch unmöglich, mit einem einzigen Aufruf von to eine Genauigkeit von mehr als 32 Bit zu erreichen arc4random, arc4random_uniform, rand oder random. Unsere obigen 32-Bit- und 64-Bit-Lösungen sollten also die besten sein, die wir erreichen können.

  • ‘Float80’ ist auf echten iOS-Geräten nicht verfügbar (es funktioniert nur auf dem Simulator).

    – Coeur

    29. November 2018 um 9:14 Uhr

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;
}

Benutzeravatar von Cœur
Coeur

Swift 4.2+

Swift 4.2 fügt native Unterstützung für einen zufälligen Wert in einem Bereich hinzu:

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)

Dok.:

Benutzeravatar von Frungi
Frungi

(float)rand() / RAND_MAX

Der vorherige Beitrag mit der Angabe “rand()” allein war falsch. Dies ist die korrekte Art, rand() zu verwenden.

Dadurch wird eine Zahl zwischen 0 -> 1 erstellt

BSD-Dokumentation:

Die Funktion rand() berechnet eine Folge pseudozufälliger Ganzzahlen in der
Bereich von 0 bis RAND_MAX (wie in der Header-Datei „stdlib.h“ definiert).

Dies ist eine Erweiterung für Float-Zufallszahlen Schnell 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 Danke, ich ändere das

    – YannSteph

    27. September 2017 um 20:11 Uhr

1419210cookie-checkGenerieren Sie einen zufälligen Float zwischen 0 und 1

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy