Gera uma flutuação aleatória entre 0 e 1

84

Estou tentando gerar um número aleatório entre 0 e 1. Continuo lendo sobre arc4random(), mas não há nenhuma informação sobre como obter um float dele. Como eu faço isso?

Jini
fonte
1
Não duplicatas, esta parece ser a única questão explicitamente relacionada aos carros alegóricos.
P i

Respostas:

139

Valor aleatório em [0, 1 [ (incluindo 0, excluindo 1):

Um pouco mais de detalhes aqui .

O intervalo real é [0, 0,9999999999767169356] , pois o limite superior é (duplo) 0xFFFFFFFF / 0x100000000.

Vladimir
fonte
Obrigado. Resposta mais direta que já vi. Vou ler em seu link e obter detalhes adicionais sobre isso. Obrigado novamente.
jini,
3
É estranho que ARC4RANDOM_MAXtenha que ser definido manualmente, mas 0x100000000é 4294967296 , que é ULONG_MAX + 1. Onde está documentado que arc4random()o máximo é de ULONG_MAXqualquer maneira?
bobobobo
@bobobobo, aqui: developer.apple.com/library/mac/#documentation/Darwin/Reference/… A função arc4random () retorna números pseudo-aleatórios no intervalo de 0 a (2 ** 32) -1
Vladimir
8
Na verdade, o valor deve ser 0xFFFFFFFF, (2 ** 32) -1 == 0x100000000 - 0x1 == 0xFFFFFFFF == UINT32_MAX conforme informado atualmente por Jörg Bühmann no link.
Josejulio
1
Os valores gerados dessa forma não têm garantia de distribuição uniforme!
kelin
107

As funções drand48 () e erand48 () retornam valores não negativos, de dupla precisão, de ponto flutuante, uniformemente distribuídos no intervalo [0,0, 1,0].

Jovan Stankovic
fonte
19
Esta deve ser a melhor resposta.
John Riselvato de
Talvez você precise atualizar um pouco a resposta, li no NSHipster que drand48precisa ser inicializado uma vez com uma semente. A documentação da Apple também sugere que ele deve ser inicializado.
dulaccc
1
A semente é necessária porque fornece a esse gerador aleatório um ponto de partida para os cálculos. Sem ela, a sequência aleatória sempre seria a mesma entre as inicializações do aplicativo.
Jovan Stankovic
Esta é a melhor resposta.
sabiland
Esta resposta não é uma resposta de precisão ideal para a double. Consulte stackoverflow.com/a/34765674/1033581 para saber como obter a melhor precisão.
Cœur
16

Para Swift 4.2+, consulte: https://stackoverflow.com/a/50733095/1033581


Abaixo estão as recomendações para uniformidade correta e precisão ideal para ObjC e Swift 4.1.

Precisão de 32 bits (ideal para Float)

Valor aleatório uniforme em [0, 1] (incluindo 0,0 e 1,0), precisão de até 32 bits:

Obj-C :

Swift :

É ideal para:

  • a Float(ou Float32) que tem uma precisão de significando de 24 bits para sua mantissa

Precisão de 48 bits (desencorajado)

É fácil atingir a precisão de 48 bits com drand48( que usa arc4random_bufsob o capô ). Mas observe que drand48 tem falhas por causa do requisito de seed e também por ser subótimo para randomizar todos os 52 bits de Double mantissa.

Valor aleatório uniforme em [0, 1] , precisão de 48 bits:

Swift :

Precisão de 64 bits (ideal para Doublee Float80)

Valor aleatório uniforme em [0, 1] (incluindo 0,0 e 1,0), até 64 bits de precisão:

Swift , usando duas chamadas para arc4random:

Swift , usando uma chamada para arc4random_buf:

É ideal para:

  • a Double(ou Float64) que tem uma precisão de significando de 52 bits para sua mantissa
  • a Float80que tem uma precisão de significando de 64 bits para sua mantissa

Notas

Comparações com outros métodos

As respostas em que o intervalo exclui um dos limites (0 ou 1) provavelmente sofrem de um viés de uniformidade e devem ser evitadas.

  • usando arc4random(), a melhor precisão é 1 / 0xFFFFFFFF (UINT32_MAX)
  • usando arc4random_uniform(), a melhor precisão é 1 / 0xFFFFFFFE (UINT32_MAX-1)
  • usando rand()( secretamente usando arc4random ), a melhor precisão é 1 / 0x7FFFFFFF (RAND_MAX)
  • usando random()( secretamente usando arc4random ), a melhor precisão é 1 / 0x7FFFFFFF (RAND_MAX)

É matematicamente impossível atingir precisão melhor do que 32 bits com uma única chamada para arc4random, arc4random_uniform, randou random. Portanto, nossas soluções acima de 32 bits e 64 bits devem ser as melhores que podemos alcançar.

Cœur
fonte
'Float80' não está disponível em dispositivos iOS reais (funciona apenas no simulador).
Cœur
10

Esta função também funciona para intervalos de flutuação negativa:

Héctor Sanchez
fonte
4
Operação de módulo estranho. use em seu Min+(Max-Min)*((float)arc4random())/ULONG_MAXlugar. O (float)elenco é apenas paranóia.
bobobobo
@bobobobo embora eu concorde com o módulo estranho, aconselho a dividir por UINT32_MAX (4294967295 sempre) em vez de ULONG_MAX (18446744073709551615 em 64 bits).
Cœur
1

O post anterior informando "rand ()" sozinho estava incorreto. Esta é a maneira correta de usar rand ().

Isso criará um número entre 0 -> 1

Documentos BSD:

A função rand () calcula uma sequência de inteiros pseudo-aleatórios no
intervalo de 0 a RAND_MAX (conforme definido pelo arquivo de cabeçalho "stdlib.h").

Leslie Godwin
fonte
1

Esta é uma extensão para o número aleatório Float Swift 3.1

YannSteph
fonte
@ Cœur Obrigado, eu mudo isso
YannSteph
1

Swift 4.2

O Swift 4.2 incluiu uma API de número aleatório nativa e bastante completa na biblioteca padrão. ( Proposta de evolução rápida SE-0202 )

Todos os tipos de número têm a função aleatória estática (em :) que pega o intervalo e retorna o número aleatório no intervalo fornecido.

Suhit Patil
fonte
0

Use isso para evitar problemas com o limite superior de arc4random ()

Observe que é aplicável para MAC_10_7, IPHONE_4_3 e superior.

malex
fonte
Há um problema de alcance fundamental com isso. É facilmente perceptível quando você define upper_bound para 10, arc4random_uniform retornará valores de 0 a 9, e o resultado final será de 0,0000 a 0,9000. Em vez disso, você deve dividir por upper_bound-1. Ainda assim, você ainda teria uma precisão arbitrariamente baixa causada por upper_bound, então você deveria aumentar upper_bound para UINT32_MAX. E você pode obter uma precisão ainda melhor usando em arc4random()*1.0 / UINT32_MAXvez de arc4random_uniform(UINT32_MAX)*1.0 / (UINT32_MAX-1).
Cœur
-1

arc4random tem um intervalo de até 0x100000000 (4294967296)

Esta é outra boa opção para gerar números aleatórios entre 0 e 1:

Gurunatha Dogi
fonte
O valor máximo de arc4random é 0xFFFFFFFF
Cœur
Obrigado @ Cœur ..max val 0xFFFFFFFF eu não sabia
Gurunatha Dogi
sua solução também é idêntica à resposta de Jovan Stankovic.
Cœur
Ohh eu não vi isso @ Cœur
Gurunatha Dogi
-4

Isso produz uma flutuação aleatória entre 0 e 1. Mais informações aqui

jhilgert00
fonte
3
Nota: fornece apenas 11 valores discretos: 0,0, 0,1, 0,2, ..., 1,0
TalkLittle
8
Sim, a operação de módulo corta o resultado de arc4random () para ficar entre 0 e 10, então ele o divide por 10. Esta resposta é realmente ruim para uso geral.
bobobobo
-4

por padrão, produz um número aleatório (float) entre 0 e 1.

eragon1189
fonte
4
Isso produz um int aleatório para mim.
AlexQueue
rand()não parece existir no iOS e, se existisse , produziria um número inteiro como em todos os outros * NIX.
jscs
2
@JoshCaswell rand()é parte de C, que por sua vez é parte de Objective-C (que é usado na programação iOS). Funções C como rand()absolutamente existem no iOS, mas arc4random()é o preferido.
Frungi de