ios - number - Genera un flotante aleatorio entre 0 y 1
swift 4 random number in range (13)
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)
arc4random()
generar un número aleatorio que esté entre 0 y 1. Sigo leyendo sobre arc4random()
, pero no hay información sobre cómo obtener un flotador de él. ¿Cómo hago esto?
¿Qué tal esta operación ((CGFloat)(rand()%100)/100)
?
Esta es la extensión para el número aleatorio 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
}
}
Esta función también funciona para rangos de flotación negativos:
float randomFloat(float Min, float Max){
return ((arc4random()%RAND_MAX)/(RAND_MAX*1.0))*(Max-Min)+Min;
}
Use esto para evitar problemas con el límite superior de arc4random ()
u_int32_t upper_bound = 1000000;
float r = arc4random_uniform(upper_bound)*1.0/upper_bound;
Tenga en cuenta que es aplicable para MAC_10_7, IPHONE_4_3 y superior.
Valor aleatorio en [0, 1 [ (incluido 0, excluyendo 1):
#define ARC4RANDOM_MAX 0x100000000
...
double val = ((double)arc4random() / ARC4RANDOM_MAX);
Un poco más detalles here .
El rango real es [0, 0.999999999767169356] , ya que el límite superior es (doble) 0xFFFFFFFF / 0x100000000.
arc4random
tiene un alcance de hasta 0x100000000 (4294967296)
Esta es otra buena opción para generar números aleatorios entre 0 y 1:
srand48(time(0)); // pseudo-random number initializer.
double r = drand48();
Para Swift 4.2+ ver: https://.com/a/50733095/1033581
Aquí hay recomendaciones de uniformidad correcta y precisión óptima para ObjC y Swift 4.1.
32 bits de precisión (óptimo para Float
)
Valor aleatorio uniforme en [0, 1] (incluyendo 0.0 y 1.0), hasta 32 bits de precisión:
Obj-C :
float val = (float)arc4random() / UINT32_MAX;
Swift :
let val = Float(arc4random()) / Float(UInt32.max)
Es óptimo para:
- un
Float
(oFloat32
) que tiene una gran precisión de 24 bits para su mantisa
Precisión de 48 bits (desalentada)
Es fácil lograr una precisión de 48 bits con drand48
( que usa arc4random_buf
debajo del capó ). Pero tenga en cuenta que drand48 tiene defectos debido a los requisitos de semilla y también por ser subóptimo para aleatorizar los 52 bits de la mantisa doble.
Valor aleatorio uniforme en [0, 1] , precisión de 48 bits:
Swift :
// seed (only needed once)
srand48(Int(Date.timeIntervalSinceReferenceDate))
// random Double value
let val = drand48()
64 bits de precisión (óptimo para Double
y Float80
)
Valor aleatorio uniforme en [0, 1] (incluyendo 0.0 y 1.0), hasta 64 bits de precisión:
Swift , usando dos llamadas a arc4random:
let val = Float80(UInt64(arc4random()) << 32 &+ UInt64(arc4random())) / Float80(UInt64.max)
Swift , usando una llamada a arc4random_buf:
var arc4random64: UInt64 = 0
arc4random_buf(&arc4random64, MemoryLayout.size(ofValue: arc4random64))
let val = Float80(arc4random64) / Float80(UInt64.max)
Es óptimo para:
- un
Double
(oFloat64
) que tiene una significativa precisión de 52 bits para su mantisa - un
Float80
que tiene una precisión significativa de 64 bits para su mantisa
Notas
Comparaciones con otros métodos
Las respuestas donde el rango excluye uno de los límites (0 o 1) probablemente sufran un sesgo de uniformidad y deben evitarse.
- usando
arc4random()
, la mejor precisión es 1 / 0xFFFFFFFF (UINT32_MAX) - usando
arc4random_uniform()
, la mejor precisión es 1 / 0xFFFFFFFE (UINT32_MAX-1) - usando
rand()
( secretamente usando arc4random ), la mejor precisión es 1 / 0x7FFFFFFF (RAND_MAX) - usando
random()
( secretamente usando arc4random ), la mejor precisión es 1 / 0x7FFFFFFF (RAND_MAX)
Es matemáticamente imposible lograr una precisión superior a 32 bits con una única llamada a arc4random
, arc4random_uniform
, rand
o al random
. Por lo tanto, nuestras soluciones anteriores de 32 bits y 64 bits deberían ser lo mejor que podamos lograr.
Swift 4.2
Swift 4.2 ha incluido una API de número aleatorio nativo y bastante completo en la biblioteca estándar. ( Propuesta de Swift Evolution SE-0202 )
let intBetween0to9 = Int.random(in: 0...9)
let doubleBetween0to1 = Double.random(in: 0...1)
Todos los tipos de números tienen la función estática random(in:) que toma el rango y devuelve el número aleatorio en el rango dado.
(float)rand() / RAND_MAX
La publicación anterior que decía "rand ()" solo era incorrecta. Esta es la forma correcta de usar rand ().
Esto creará un número entre 0 -> 1
Documentos de BSD:
La función rand () calcula una secuencia de enteros pseudoaleatorios en el
rango de 0 a RAND_MAX (según lo definido por el archivo de encabezado "stdlib.h").
// Seed (only once)
srand48(time(0));
double x = drand48();
// Swift version
// Seed (only once)
srand48(Int(Date().timeIntervalSince1970))
let x = drand48()
Las funciones drand48 () y erand48 () devuelven valores de punto flotante no negativos, de doble precisión, distribuidos uniformemente en el intervalo [0.0, 1.0].
float x = arc4random() % 11 * 0.1;
Eso produce una flotación aleatoria entre 0 y 1. Más información aquí
rand()
por defecto produce un número aleatorio (float) entre 0 y 1.